blob: 21edf9f0b16664ead37e340e5dcca66b89c89846 [file] [log] [blame]
Nanang Izzuddin57b88572009-04-01 12:05:34 +00001/* $Id$ */
2/*
3 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include <pjmedia-codec/g7221.h>
21#include <pjmedia/codec.h>
22#include <pjmedia/errno.h>
23#include <pjmedia/endpoint.h>
24#include <pjmedia/port.h>
25#include <pjmedia/silencedet.h>
26#include <pj/assert.h>
27#include <pj/log.h>
28#include <pj/math.h>
29#include <pj/pool.h>
30#include <pj/string.h>
31#include <pj/os.h>
32
33/*
34 * Only build this file if PJMEDIA_HAS_G7221_CODEC != 0
35 */
36#if defined(PJMEDIA_HAS_G7221_CODEC) && PJMEDIA_HAS_G7221_CODEC!=0
37
Nanang Izzuddin56e380a2009-04-15 14:45:41 +000038#include "../../../third_party/g7221/common/defs.h"
Nanang Izzuddin57b88572009-04-01 12:05:34 +000039
40#define THIS_FILE "g7221.c"
41
42/* Codec tag, it is the SDP encoding name and also MIME subtype name */
43#define CODEC_TAG "G7221"
44
45/* Sampling rates definition */
46#define WB_SAMPLE_RATE 16000
47#define UWB_SAMPLE_RATE 32000
48
49/* Maximum number of samples per frame. */
50#define MAX_SAMPLES_PER_FRAME (UWB_SAMPLE_RATE * 20 / 1000)
51
52/* Maximum number of codec params. */
53#define MAX_CODEC_MODES 8
54#define START_RSV_MODES_IDX 6
55
56
57/* Prototypes for G722.1 codec factory */
58static pj_status_t test_alloc( pjmedia_codec_factory *factory,
59 const pjmedia_codec_info *id );
60static pj_status_t default_attr( pjmedia_codec_factory *factory,
61 const pjmedia_codec_info *id,
62 pjmedia_codec_param *attr );
63static pj_status_t enum_codecs( pjmedia_codec_factory *factory,
64 unsigned *count,
65 pjmedia_codec_info codecs[]);
66static pj_status_t alloc_codec( pjmedia_codec_factory *factory,
67 const pjmedia_codec_info *id,
68 pjmedia_codec **p_codec);
69static pj_status_t dealloc_codec( pjmedia_codec_factory *factory,
70 pjmedia_codec *codec );
71
72/* Prototypes for G722.1 codec implementation. */
73static pj_status_t codec_init( pjmedia_codec *codec,
74 pj_pool_t *pool );
75static pj_status_t codec_open( pjmedia_codec *codec,
76 pjmedia_codec_param *attr );
77static pj_status_t codec_close( pjmedia_codec *codec );
78static pj_status_t codec_modify(pjmedia_codec *codec,
79 const pjmedia_codec_param *attr );
80static pj_status_t codec_parse( pjmedia_codec *codec,
81 void *pkt,
82 pj_size_t pkt_size,
83 const pj_timestamp *ts,
84 unsigned *frame_cnt,
85 pjmedia_frame frames[]);
86static pj_status_t codec_encode( pjmedia_codec *codec,
87 const struct pjmedia_frame *input,
88 unsigned output_buf_len,
89 struct pjmedia_frame *output);
90static pj_status_t codec_decode( pjmedia_codec *codec,
91 const struct pjmedia_frame *input,
92 unsigned output_buf_len,
93 struct pjmedia_frame *output);
94static pj_status_t codec_recover( pjmedia_codec *codec,
95 unsigned output_buf_len,
96 struct pjmedia_frame *output);
97
98/* Definition for G722.1 codec operations. */
99static pjmedia_codec_op codec_op =
100{
101 &codec_init,
102 &codec_open,
103 &codec_close,
104 &codec_modify,
105 &codec_parse,
106 &codec_encode,
107 &codec_decode,
108 &codec_recover
109};
110
111/* Definition for G722.1 codec factory operations. */
112static pjmedia_codec_factory_op codec_factory_op =
113{
114 &test_alloc,
115 &default_attr,
116 &enum_codecs,
117 &alloc_codec,
118 &dealloc_codec
119};
120
121
122/* Structure of G722.1 mode */
123typedef struct codec_mode
124{
125 pj_bool_t enabled; /* Is this mode enabled? */
126 pj_uint8_t pt; /* Payload type. */
127 unsigned sample_rate; /* Default sampling rate to be used.*/
128 unsigned bitrate; /* Bitrate. */
129 char bitrate_str[8]; /* Bitrate in string. */
130} codec_mode;
131
132
133/* G722.1 codec factory */
134static struct codec_factory {
135 pjmedia_codec_factory base; /**< Base class. */
136 pjmedia_endpt *endpt; /**< PJMEDIA endpoint instance. */
137 pj_pool_t *pool; /**< Codec factory pool. */
138 pj_mutex_t *mutex; /**< Codec factory mutex. */
139
140 unsigned mode_count; /**< Number of G722.1 modes. */
141 codec_mode modes[MAX_CODEC_MODES]; /**< The G722.1 modes. */
142 unsigned mode_rsv_start;/**< Start index of G722.1 non-
143 standard modes, currently
144 there can only be up to two
145 non-standard modes enabled
146 at the same time. */
147} codec_factory;
148
149/* G722.1 codec private data. */
150typedef struct codec_private {
151 pj_pool_t *pool; /**< Pool for each instance. */
152 pj_bool_t plc_enabled; /**< PLC enabled? */
153 pj_bool_t vad_enabled; /**< VAD enabled? */
154 pjmedia_silence_det *vad; /**< PJMEDIA VAD instance. */
155 pj_timestamp last_tx; /**< Timestamp of last transmit.*/
156
157 /* ITU ref implementation seems to leave the codec engine states to be
158 * managed by the application, so here we go.
159 */
160
161 /* Common engine state */
162 pj_uint16_t samples_per_frame; /**< Samples per frame. */
163 pj_uint16_t bitrate; /**< Coded stream bitrate. */
164 pj_uint16_t frame_size; /**< Coded frame size. */
165 pj_uint16_t frame_size_bits; /**< Coded frame size in bits. */
166 pj_uint16_t number_of_regions; /**< Number of regions. */
167
168 /* Encoder specific state */
169 Word16 *enc_old_frame;
170
171 /* Decoder specific state */
172 Word16 *dec_old_frame;
173 Rand_Obj dec_randobj;
174 Word16 dec_old_mag_shift;
175 Word16 *dec_old_mlt_coefs;
176} codec_private_t;
177
178/*
179 * Helper function for looking up mode based on payload type.
180 */
181static codec_mode* lookup_mode(unsigned pt)
182{
183 codec_mode* mode = NULL;
184 unsigned i;
185
186 for (i = 0; i < codec_factory.mode_count; ++i) {
187 mode = &codec_factory.modes[i];
188 if (mode->pt == pt)
189 break;
190 }
191
192 return mode;
193}
194
195/*
196 * Helper function to validate G722.1 mode. Valid modes are defined as:
197 * 1. sample rate must be 16kHz or 32kHz,
198 * 2. bitrate:
199 * - for sampling rate 16kHz: 16000 to 32000 bps, it must be a multiple
200 * of 400 (to keep RTP payload octed-aligned)
201 * - for sampling rate 32kHz: 24000 to 48000 bps, it must be a multiple
202 * of 400 (to keep RTP payload octed-aligned)
203 */
204static pj_bool_t validate_mode(unsigned sample_rate, unsigned bitrate)
205{
206 if (sample_rate == WB_SAMPLE_RATE) {
207 if (bitrate < 16000 || bitrate > 32000 ||
208 ((bitrate-16000) % 400 != 0))
209 {
210 return PJ_FALSE;
211 }
212 } else if (sample_rate == UWB_SAMPLE_RATE) {
213 if (bitrate < 24000 || bitrate > 48000 ||
214 ((bitrate-24000) % 400 != 0))
215 {
216 return PJ_FALSE;
217 }
218 } else {
219 return PJ_FALSE;
220 }
221
222 return PJ_TRUE;
223}
224
225/*
226 * Initialize and register G722.1 codec factory to pjmedia endpoint.
227 */
228PJ_DEF(pj_status_t) pjmedia_codec_g7221_init( pjmedia_endpt *endpt )
229{
230 pjmedia_codec_mgr *codec_mgr;
231 codec_mode *mode;
232 pj_status_t status;
233
234 if (codec_factory.pool != NULL) {
235 /* Already initialized. */
236 return PJ_SUCCESS;
237 }
238
239 /* Initialize codec modes, by default all standard bitrates are enabled */
Nanang Izzuddin27659812009-04-15 17:50:50 +0000240 codec_factory.mode_count = 0;
241
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000242 mode = &codec_factory.modes[codec_factory.mode_count++];
243 mode->enabled = PJ_TRUE;
244 mode->pt = PJMEDIA_RTP_PT_G722_1_24;
245 mode->sample_rate = WB_SAMPLE_RATE;
246 mode->bitrate = 24000;
247 pj_utoa(mode->bitrate, mode->bitrate_str);
248
249 mode = &codec_factory.modes[codec_factory.mode_count++];
250 mode->enabled = PJ_TRUE;
251 mode->pt = PJMEDIA_RTP_PT_G722_1_32;
252 mode->sample_rate = WB_SAMPLE_RATE;
253 mode->bitrate = 32000;
254 pj_utoa(mode->bitrate, mode->bitrate_str);
255
256 mode = &codec_factory.modes[codec_factory.mode_count++];
257 mode->enabled = PJ_TRUE;
258 mode->pt = PJMEDIA_RTP_PT_G7221C_24;
259 mode->sample_rate = UWB_SAMPLE_RATE;
260 mode->bitrate = 24000;
261 pj_utoa(mode->bitrate, mode->bitrate_str);
262
263 mode = &codec_factory.modes[codec_factory.mode_count++];
264 mode->enabled = PJ_TRUE;
265 mode->pt = PJMEDIA_RTP_PT_G7221C_32;
266 mode->sample_rate = UWB_SAMPLE_RATE;
267 mode->bitrate = 32000;
268 pj_utoa(mode->bitrate, mode->bitrate_str);
269
270 mode = &codec_factory.modes[codec_factory.mode_count++];
271 mode->enabled = PJ_TRUE;
272 mode->pt = PJMEDIA_RTP_PT_G7221C_48;
273 mode->sample_rate = UWB_SAMPLE_RATE;
274 mode->bitrate = 48000;
275 pj_utoa(mode->bitrate, mode->bitrate_str);
276
277 /* Non-standard bitrates */
278
279 /* Bitrate 16kbps is non-standard but rather commonly used. */
280 mode = &codec_factory.modes[codec_factory.mode_count++];
281 mode->enabled = PJ_FALSE;
282 mode->pt = PJMEDIA_RTP_PT_G722_1_16;
283 mode->sample_rate = WB_SAMPLE_RATE;
284 mode->bitrate = 16000;
285 pj_utoa(mode->bitrate, mode->bitrate_str);
286
287 /* Reserved two modes for non-standard bitrates */
288 codec_factory.mode_rsv_start = codec_factory.mode_count;
289 mode = &codec_factory.modes[codec_factory.mode_count++];
290 mode->enabled = PJ_FALSE;
291 mode->pt = PJMEDIA_RTP_PT_G7221_RSV1;
292
293 mode = &codec_factory.modes[codec_factory.mode_count++];
294 mode->enabled = PJ_FALSE;
295 mode->pt = PJMEDIA_RTP_PT_G7221_RSV2;
296
297 pj_assert(codec_factory.mode_count <= MAX_CODEC_MODES);
298
299 /* Create G722.1 codec factory. */
300 codec_factory.base.op = &codec_factory_op;
301 codec_factory.base.factory_data = NULL;
302 codec_factory.endpt = endpt;
303
304 codec_factory.pool = pjmedia_endpt_create_pool(endpt, "G722.1 codec",
305 4000, 4000);
306 if (!codec_factory.pool)
307 return PJ_ENOMEM;
308
309 /* Create mutex. */
310 status = pj_mutex_create_simple(codec_factory.pool, "G722.1 codec",
311 &codec_factory.mutex);
312 if (status != PJ_SUCCESS)
313 goto on_error;
314
315 /* Get the codec manager. */
316 codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);
317 if (!codec_mgr) {
318 status = PJ_EINVALIDOP;
319 goto on_error;
320 }
321
322 /* Register codec factory to endpoint. */
323 status = pjmedia_codec_mgr_register_factory(codec_mgr,
324 &codec_factory.base);
325 if (status != PJ_SUCCESS)
326 goto on_error;
327
328 /* Done. */
329 return PJ_SUCCESS;
330
331on_error:
332 if (codec_factory.mutex) {
333 pj_mutex_destroy(codec_factory.mutex);
334 codec_factory.mutex = NULL;
335 }
336
337 pj_pool_release(codec_factory.pool);
338 codec_factory.pool = NULL;
339 return status;
340}
341
342
343/**
344 * Enable and disable G722.1 modes, including non-standard modes.
345 */
346PJ_DEF(pj_status_t) pjmedia_codec_g7221_set_mode(unsigned sample_rate,
347 unsigned bitrate,
348 pj_bool_t enabled)
349{
350 unsigned i;
351
352 /* Validate mode */
353 if (!validate_mode(sample_rate, bitrate))
354 return PJMEDIA_CODEC_EINMODE;
355
356 /* Look up in factory modes table */
357 for (i = 0; i < codec_factory.mode_count; ++i) {
358 if (codec_factory.modes[i].sample_rate == sample_rate &&
359 codec_factory.modes[i].bitrate == bitrate)
360 {
361 codec_factory.modes[i].enabled = enabled;
362 return PJ_SUCCESS;
363 }
364 }
365
366 /* Mode not found in modes table, this may be a request to enable
367 * a non-standard G722.1 mode.
368 */
369
370 /* Non-standard mode need to be initialized first before user
371 * can disable it.
372 */
373 if (!enabled)
374 return PJ_ENOTFOUND;
375
376 /* Initialize a non-standard mode, look for available space. */
377 for (i = codec_factory.mode_rsv_start;
378 i < codec_factory.mode_count; ++i)
379 {
380 if (!codec_factory.modes[i].enabled)
381 {
382 codec_mode *mode = &codec_factory.modes[i];
383 mode->enabled = PJ_TRUE;
384 mode->sample_rate = sample_rate;
385 mode->bitrate = bitrate;
386 pj_utoa(mode->bitrate, mode->bitrate_str);
387
388 return PJ_SUCCESS;
389 }
390 }
391
392 /* No space for non-standard mode. */
393 return PJ_ETOOMANY;
394}
395
396
397/*
398 * Unregister G722.1 codec factory from pjmedia endpoint.
399 */
400PJ_DEF(pj_status_t) pjmedia_codec_g7221_deinit(void)
401{
402 pjmedia_codec_mgr *codec_mgr;
403 pj_status_t status;
404
405 if (codec_factory.pool == NULL) {
406 /* Already deinitialized */
407 return PJ_SUCCESS;
408 }
409
410 pj_mutex_lock(codec_factory.mutex);
411
412 /* Get the codec manager. */
413 codec_mgr = pjmedia_endpt_get_codec_mgr(codec_factory.endpt);
414 if (!codec_mgr) {
415 pj_pool_release(codec_factory.pool);
416 codec_factory.pool = NULL;
417 return PJ_EINVALIDOP;
418 }
419
420 /* Unregister G722.1 codec factory. */
421 status = pjmedia_codec_mgr_unregister_factory(codec_mgr,
422 &codec_factory.base);
423
424 /* Destroy mutex. */
425 pj_mutex_destroy(codec_factory.mutex);
426
427 /* Destroy pool. */
428 pj_pool_release(codec_factory.pool);
429 codec_factory.pool = NULL;
430
431 return status;
432}
433
434/*
435 * Check if factory can allocate the specified codec.
436 */
437static pj_status_t test_alloc( pjmedia_codec_factory *factory,
438 const pjmedia_codec_info *info )
439{
440 PJ_UNUSED_ARG(factory);
441
442 /* Type MUST be audio. */
443 if (info->type != PJMEDIA_TYPE_AUDIO)
444 return PJMEDIA_CODEC_EUNSUP;
445
446 /* Check encoding name. */
447 if (pj_stricmp2(&info->encoding_name, CODEC_TAG) != 0)
448 return PJMEDIA_CODEC_EUNSUP;
449
450 /* Check clock-rate */
451 if (info->clock_rate != WB_SAMPLE_RATE &&
452 info->clock_rate != UWB_SAMPLE_RATE)
453 {
454 return PJMEDIA_CODEC_EUNSUP;
455 }
456
457 return PJ_SUCCESS;
458}
459
460/*
461 * Generate default attribute.
462 */
463static pj_status_t default_attr ( pjmedia_codec_factory *factory,
464 const pjmedia_codec_info *id,
465 pjmedia_codec_param *attr )
466{
467 codec_mode *mode;
468
469 PJ_ASSERT_RETURN(factory==&codec_factory.base, PJ_EINVAL);
470
471 pj_bzero(attr, sizeof(pjmedia_codec_param));
472
473 mode = lookup_mode(id->pt);
474 if (mode == NULL || !mode->enabled)
475 return PJMEDIA_CODEC_EUNSUP;
476
477 attr->info.pt = (pj_uint8_t)id->pt;
478 attr->info.channel_cnt = 1;
479 attr->info.clock_rate = mode->sample_rate;
480 attr->info.max_bps = mode->bitrate;
481 attr->info.avg_bps = mode->bitrate;
482 attr->info.pcm_bits_per_sample = 16;
483 attr->info.frm_ptime = 20;
484
485 /* Default flags. */
486 attr->setting.plc = 1;
487 attr->setting.vad = 0;
488 attr->setting.frm_per_pkt = 1;
489
490 /* Default FMTP setting */
491 attr->setting.dec_fmtp.cnt = 1;
492 attr->setting.dec_fmtp.param[0].name = pj_str("bitrate");
493 attr->setting.dec_fmtp.param[0].val = pj_str(mode->bitrate_str);
494
495 return PJ_SUCCESS;
496}
497
498/*
499 * Enum codecs supported by this factory.
500 */
501static pj_status_t enum_codecs( pjmedia_codec_factory *factory,
502 unsigned *count,
503 pjmedia_codec_info codecs[])
504{
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000505 unsigned i, max_cnt;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000506
507 PJ_ASSERT_RETURN(factory==&codec_factory.base, PJ_EINVAL);
508 PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);
509
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000510 max_cnt = *count;
511 *count = 0;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000512
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000513 for (i=0; (i < codec_factory.mode_count) && (*count < max_cnt); ++i)
514 {
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000515 if (!codec_factory.modes[i].enabled)
516 continue;
517
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000518 pj_bzero(&codecs[*count], sizeof(pjmedia_codec_info));
519 codecs[*count].encoding_name = pj_str((char*)CODEC_TAG);
520 codecs[*count].pt = codec_factory.modes[i].pt;
521 codecs[*count].type = PJMEDIA_TYPE_AUDIO;
522 codecs[*count].clock_rate = codec_factory.modes[i].sample_rate;
523 codecs[*count].channel_cnt = 1;
524
525 ++ *count;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000526 }
527
528 return PJ_SUCCESS;
529}
530
531/*
532 * Allocate a new codec instance.
533 */
534static pj_status_t alloc_codec( pjmedia_codec_factory *factory,
535 const pjmedia_codec_info *id,
536 pjmedia_codec **p_codec)
537{
538 codec_private_t *codec_data;
539 pjmedia_codec *codec;
540 pj_pool_t *pool;
541 pj_status_t status;
542
543 PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);
544 PJ_ASSERT_RETURN(factory == &codec_factory.base, PJ_EINVAL);
545
546 pj_mutex_lock(codec_factory.mutex);
547
548 /* Create pool for codec instance */
549 pool = pjmedia_endpt_create_pool(codec_factory.endpt, "G7221", 512, 512);
550 codec = PJ_POOL_ZALLOC_T(pool, pjmedia_codec);
551 codec->op = &codec_op;
552 codec->factory = factory;
553 codec->codec_data = PJ_POOL_ZALLOC_T(pool, codec_private_t);
554 codec_data = (codec_private_t*) codec->codec_data;
555 codec_data->pool = pool;
556
557 /* Create silence detector */
558 status = pjmedia_silence_det_create(pool, id->clock_rate,
559 id->clock_rate * 20 / 1000,
560 &codec_data->vad);
561 if (status != PJ_SUCCESS) {
562 pj_mutex_unlock(codec_factory.mutex);
563 return status;
564 }
565
566 pj_mutex_unlock(codec_factory.mutex);
567
568 *p_codec = codec;
569 return PJ_SUCCESS;
570}
571
572/*
573 * Free codec.
574 */
575static pj_status_t dealloc_codec( pjmedia_codec_factory *factory,
576 pjmedia_codec *codec )
577{
578 codec_private_t *codec_data;
579 pj_pool_t *pool;
580
581 PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);
582 PJ_ASSERT_RETURN(factory == &codec_factory.base, PJ_EINVAL);
583
584 /* Close codec, if it's not closed. */
585 codec_data = (codec_private_t*) codec->codec_data;
586 pool = codec_data->pool;
587 codec_close(codec);
588
589 /* Release codec pool */
590 pj_pool_release(pool);
591
592 return PJ_SUCCESS;
593}
594
595/*
596 * Init codec.
597 */
598static pj_status_t codec_init( pjmedia_codec *codec,
599 pj_pool_t *pool )
600{
601 PJ_UNUSED_ARG(codec);
602 PJ_UNUSED_ARG(pool);
603 return PJ_SUCCESS;
604}
605
606/*
607 * Open codec.
608 */
609static pj_status_t codec_open( pjmedia_codec *codec,
610 pjmedia_codec_param *attr )
611{
612 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
613 pj_pool_t *pool;
614 unsigned tmp;
615
616 /* Validation mode first! */
617 if (!validate_mode(attr->info.clock_rate, attr->info.avg_bps))
618 return PJMEDIA_CODEC_EINMODE;
619
620 pool = codec_data->pool;
621
622 /* Initialize common state */
623 codec_data->vad_enabled = (attr->setting.vad != 0);
624 codec_data->plc_enabled = (attr->setting.plc != 0);
625
626 codec_data->bitrate = (pj_uint16_t)attr->info.avg_bps;
627 codec_data->frame_size_bits = (pj_uint16_t)(attr->info.avg_bps*20/1000);
628 codec_data->frame_size = (pj_uint16_t)(codec_data->frame_size_bits>>3);
629 codec_data->samples_per_frame = (pj_uint16_t)
630 (attr->info.clock_rate*20/1000);
631 codec_data->number_of_regions = (pj_uint16_t)
632 (attr->info.clock_rate <= WB_SAMPLE_RATE?
633 NUMBER_OF_REGIONS:MAX_NUMBER_OF_REGIONS);
634
635 /* Initialize encoder state */
636 tmp = codec_data->samples_per_frame << 1;
637 codec_data->enc_old_frame = (Word16*)pj_pool_zalloc(pool, tmp);
638
639 /* Initialize decoder state */
640 tmp = codec_data->samples_per_frame;
641 codec_data->dec_old_frame = (Word16*)pj_pool_zalloc(pool, tmp);
642
643 tmp = codec_data->samples_per_frame << 1;
644 codec_data->dec_old_mlt_coefs = (Word16*)pj_pool_zalloc(pool, tmp);
645
646 codec_data->dec_randobj.seed0 = 1;
647 codec_data->dec_randobj.seed1 = 1;
648 codec_data->dec_randobj.seed2 = 1;
649 codec_data->dec_randobj.seed3 = 1;
650
651 return PJ_SUCCESS;
652}
653
654/*
655 * Close codec.
656 */
657static pj_status_t codec_close( pjmedia_codec *codec )
658{
659 PJ_UNUSED_ARG(codec);
660
661 return PJ_SUCCESS;
662}
663
664
665/*
666 * Modify codec settings.
667 */
668static pj_status_t codec_modify( pjmedia_codec *codec,
669 const pjmedia_codec_param *attr )
670{
671 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
672
673 codec_data->vad_enabled = (attr->setting.vad != 0);
674 codec_data->plc_enabled = (attr->setting.plc != 0);
675
676 return PJ_SUCCESS;
677}
678
679/*
680 * Get frames in the packet.
681 */
682static pj_status_t codec_parse( pjmedia_codec *codec,
683 void *pkt,
684 pj_size_t pkt_size,
685 const pj_timestamp *ts,
686 unsigned *frame_cnt,
687 pjmedia_frame frames[])
688{
689 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
690 unsigned count = 0;
691
692 PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);
693
694 /* Parse based on fixed frame size. */
695 while (pkt_size >= codec_data->frame_size && count < *frame_cnt) {
696 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;
697 frames[count].buf = pkt;
698 frames[count].size = codec_data->frame_size;
699 frames[count].timestamp.u64 = ts->u64 +
700 count * codec_data->samples_per_frame;
701
702 pkt = (pj_uint8_t*)pkt + codec_data->frame_size;
703 pkt_size -= codec_data->frame_size;
704
705 ++count;
706 }
707
708 pj_assert(pkt_size == 0);
709 *frame_cnt = count;
710
711 return PJ_SUCCESS;
712}
713
714/*
715 * Encode frames.
716 */
717static pj_status_t codec_encode( pjmedia_codec *codec,
718 const struct pjmedia_frame *input,
719 unsigned output_buf_len,
720 struct pjmedia_frame *output)
721{
722 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
723 Word16 mlt_coefs[MAX_SAMPLES_PER_FRAME];
724 Word16 mag_shift;
725
726 /* Check frame in & out size */
727 PJ_ASSERT_RETURN((pj_uint16_t)input->size ==
728 (codec_data->samples_per_frame<<1),
729 PJMEDIA_CODEC_EPCMTOOSHORT);
730 PJ_ASSERT_RETURN(output_buf_len >= codec_data->frame_size,
731 PJMEDIA_CODEC_EFRMTOOSHORT);
732
733 /* Apply silence detection if VAD is enabled */
734 if (codec_data->vad_enabled) {
735 pj_bool_t is_silence;
736 pj_int32_t silence_duration;
737
738 pj_assert(codec_data->vad);
739
740 silence_duration = pj_timestamp_diff32(&codec_data->last_tx,
741 &input->timestamp);
742
743 is_silence = pjmedia_silence_det_detect(codec_data->vad,
744 (const pj_int16_t*) input->buf,
745 (input->size >> 1),
746 NULL);
747 if (is_silence &&
748 PJMEDIA_CODEC_MAX_SILENCE_PERIOD != -1 &&
749 silence_duration < (PJMEDIA_CODEC_MAX_SILENCE_PERIOD *
750 (int)codec_data->samples_per_frame / 20))
751 {
752 output->type = PJMEDIA_FRAME_TYPE_NONE;
753 output->buf = NULL;
754 output->size = 0;
755 output->timestamp = input->timestamp;
756 return PJ_SUCCESS;
757 } else {
758 codec_data->last_tx = input->timestamp;
759 }
760 }
761
762 /* Convert input samples to rmlt coefs */
763 mag_shift = samples_to_rmlt_coefs((Word16*)input->buf,
764 codec_data->enc_old_frame,
765 mlt_coefs,
766 codec_data->samples_per_frame);
767
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000768 /* Encode the mlt coefs. Note that encoder output stream is 16 bit array,
769 * so we need to take care about endianness.
770 */
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000771 encoder(codec_data->frame_size_bits,
772 codec_data->number_of_regions,
773 mlt_coefs,
774 mag_shift,
775 output->buf);
776
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000777#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
778 {
779 pj_uint16_t *p, *p_end;
780
781 p = (pj_uint16_t*)output->buf;
782 p_end = p + codec_data->frame_size/2;
783 while (p < p_end) {
784 *p = pj_htons(*p);
785 ++p;
786 }
787 }
788#endif
789
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000790 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
791 output->size = codec_data->frame_size;
792
793 return PJ_SUCCESS;
794}
795
796/*
797 * Decode frame.
798 */
799static pj_status_t codec_decode( pjmedia_codec *codec,
800 const struct pjmedia_frame *input,
801 unsigned output_buf_len,
802 struct pjmedia_frame *output)
803{
804 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
805 Word16 mlt_coefs[MAX_SAMPLES_PER_FRAME];
806 Word16 mag_shift;
807 Bit_Obj bitobj;
808 Word16 frame_error_flag = 0;
809
810 /* Check frame out length size */
811 PJ_ASSERT_RETURN(output_buf_len >=
812 (unsigned)(codec_data->samples_per_frame<<1),
813 PJMEDIA_CODEC_EPCMTOOSHORT);
814
815 /* If input is NULL, perform PLC by settting frame_error_flag to 1 */
816 if (input) {
817 /* Check frame in length size */
818 PJ_ASSERT_RETURN((pj_uint16_t)input->size == codec_data->frame_size,
819 PJMEDIA_CODEC_EFRMINLEN);
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000820
821 /* Decoder requires input of 16-bits array, so we need to take care
822 * about endianness.
823 */
824#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
825 {
826 pj_uint16_t *p, *p_end;
827
828 p = (pj_uint16_t*)input->buf;
829 p_end = p + codec_data->frame_size/2;
830 while (p < p_end) {
831 *p = pj_ntohs(*p);
832 ++p;
833 }
834 }
835#endif
836
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000837 bitobj.code_word_ptr = (Word16*)input->buf;
838 bitobj.current_word = *bitobj.code_word_ptr;
839 bitobj.code_bit_count = 0;
840 bitobj.number_of_bits_left = codec_data->frame_size_bits;
841 } else {
842 pj_bzero(&bitobj, sizeof(bitobj));
843 frame_error_flag = 1;
844 }
845
846 /* Process the input frame to get mlt coefs */
847 decoder(&bitobj,
848 &codec_data->dec_randobj,
849 codec_data->number_of_regions,
850 mlt_coefs,
851 &mag_shift,
852 &codec_data->dec_old_mag_shift,
853 codec_data->dec_old_mlt_coefs,
854 frame_error_flag);
855
856 /* Convert the mlt_coefs to PCM samples */
857 rmlt_coefs_to_samples(mlt_coefs,
858 codec_data->dec_old_frame,
859 (Word16*)output->buf,
860 codec_data->samples_per_frame,
861 mag_shift);
862
863 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
864 output->size = codec_data->samples_per_frame << 1;
865
866 return PJ_SUCCESS;
867}
868
869/*
870 * Recover lost frame.
871 */
872static pj_status_t codec_recover( pjmedia_codec *codec,
873 unsigned output_buf_len,
874 struct pjmedia_frame *output)
875{
876 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
877
878 /* Use native PLC when PLC is enabled. */
879 if (codec_data->plc_enabled)
880 return codec_decode(codec, NULL, output_buf_len, output);
881
882 /* Otherwise just return zero-fill frame. */
883 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
884 output->size = codec_data->samples_per_frame << 1;
885
886 pjmedia_zero_samples((pj_int16_t*)output->buf,
887 codec_data->samples_per_frame);
888
889 return PJ_SUCCESS;
890}
891
892#endif /* PJMEDIA_HAS_G7221_CODEC */