blob: e4eb1aee8c56946f2dd07269b49ace24dc85cb76 [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
Benny Prijono3594ab32009-04-18 14:29:28 +0000225#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
226PJ_INLINE(void) swap_bytes(pj_uint16_t *buf, unsigned count)
227{
228 pj_uint16_t *end = buf + count;
229 while (buf != end) {
230 *buf = (pj_uint16_t)((*buf << 8) | (*buf >> 8));
231 ++buf;
232 }
233}
234#else
235#define swap_bytes(buf, count)
236#endif
237
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000238/*
239 * Initialize and register G722.1 codec factory to pjmedia endpoint.
240 */
241PJ_DEF(pj_status_t) pjmedia_codec_g7221_init( pjmedia_endpt *endpt )
242{
243 pjmedia_codec_mgr *codec_mgr;
244 codec_mode *mode;
245 pj_status_t status;
246
247 if (codec_factory.pool != NULL) {
248 /* Already initialized. */
249 return PJ_SUCCESS;
250 }
251
252 /* Initialize codec modes, by default all standard bitrates are enabled */
Nanang Izzuddin27659812009-04-15 17:50:50 +0000253 codec_factory.mode_count = 0;
254
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000255 mode = &codec_factory.modes[codec_factory.mode_count++];
256 mode->enabled = PJ_TRUE;
257 mode->pt = PJMEDIA_RTP_PT_G722_1_24;
258 mode->sample_rate = WB_SAMPLE_RATE;
259 mode->bitrate = 24000;
260 pj_utoa(mode->bitrate, mode->bitrate_str);
261
262 mode = &codec_factory.modes[codec_factory.mode_count++];
263 mode->enabled = PJ_TRUE;
264 mode->pt = PJMEDIA_RTP_PT_G722_1_32;
265 mode->sample_rate = WB_SAMPLE_RATE;
266 mode->bitrate = 32000;
267 pj_utoa(mode->bitrate, mode->bitrate_str);
268
269 mode = &codec_factory.modes[codec_factory.mode_count++];
270 mode->enabled = PJ_TRUE;
271 mode->pt = PJMEDIA_RTP_PT_G7221C_24;
272 mode->sample_rate = UWB_SAMPLE_RATE;
273 mode->bitrate = 24000;
274 pj_utoa(mode->bitrate, mode->bitrate_str);
275
276 mode = &codec_factory.modes[codec_factory.mode_count++];
277 mode->enabled = PJ_TRUE;
278 mode->pt = PJMEDIA_RTP_PT_G7221C_32;
279 mode->sample_rate = UWB_SAMPLE_RATE;
280 mode->bitrate = 32000;
281 pj_utoa(mode->bitrate, mode->bitrate_str);
282
283 mode = &codec_factory.modes[codec_factory.mode_count++];
284 mode->enabled = PJ_TRUE;
285 mode->pt = PJMEDIA_RTP_PT_G7221C_48;
286 mode->sample_rate = UWB_SAMPLE_RATE;
287 mode->bitrate = 48000;
288 pj_utoa(mode->bitrate, mode->bitrate_str);
289
290 /* Non-standard bitrates */
291
292 /* Bitrate 16kbps is non-standard but rather commonly used. */
293 mode = &codec_factory.modes[codec_factory.mode_count++];
294 mode->enabled = PJ_FALSE;
295 mode->pt = PJMEDIA_RTP_PT_G722_1_16;
296 mode->sample_rate = WB_SAMPLE_RATE;
297 mode->bitrate = 16000;
298 pj_utoa(mode->bitrate, mode->bitrate_str);
299
300 /* Reserved two modes for non-standard bitrates */
301 codec_factory.mode_rsv_start = codec_factory.mode_count;
302 mode = &codec_factory.modes[codec_factory.mode_count++];
303 mode->enabled = PJ_FALSE;
304 mode->pt = PJMEDIA_RTP_PT_G7221_RSV1;
305
306 mode = &codec_factory.modes[codec_factory.mode_count++];
307 mode->enabled = PJ_FALSE;
308 mode->pt = PJMEDIA_RTP_PT_G7221_RSV2;
309
310 pj_assert(codec_factory.mode_count <= MAX_CODEC_MODES);
311
312 /* Create G722.1 codec factory. */
313 codec_factory.base.op = &codec_factory_op;
314 codec_factory.base.factory_data = NULL;
315 codec_factory.endpt = endpt;
316
317 codec_factory.pool = pjmedia_endpt_create_pool(endpt, "G722.1 codec",
318 4000, 4000);
319 if (!codec_factory.pool)
320 return PJ_ENOMEM;
321
322 /* Create mutex. */
323 status = pj_mutex_create_simple(codec_factory.pool, "G722.1 codec",
324 &codec_factory.mutex);
325 if (status != PJ_SUCCESS)
326 goto on_error;
327
328 /* Get the codec manager. */
329 codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);
330 if (!codec_mgr) {
331 status = PJ_EINVALIDOP;
332 goto on_error;
333 }
334
335 /* Register codec factory to endpoint. */
336 status = pjmedia_codec_mgr_register_factory(codec_mgr,
337 &codec_factory.base);
338 if (status != PJ_SUCCESS)
339 goto on_error;
340
341 /* Done. */
342 return PJ_SUCCESS;
343
344on_error:
345 if (codec_factory.mutex) {
346 pj_mutex_destroy(codec_factory.mutex);
347 codec_factory.mutex = NULL;
348 }
349
350 pj_pool_release(codec_factory.pool);
351 codec_factory.pool = NULL;
352 return status;
353}
354
355
356/**
357 * Enable and disable G722.1 modes, including non-standard modes.
358 */
359PJ_DEF(pj_status_t) pjmedia_codec_g7221_set_mode(unsigned sample_rate,
360 unsigned bitrate,
361 pj_bool_t enabled)
362{
363 unsigned i;
364
365 /* Validate mode */
366 if (!validate_mode(sample_rate, bitrate))
367 return PJMEDIA_CODEC_EINMODE;
368
369 /* Look up in factory modes table */
370 for (i = 0; i < codec_factory.mode_count; ++i) {
371 if (codec_factory.modes[i].sample_rate == sample_rate &&
372 codec_factory.modes[i].bitrate == bitrate)
373 {
374 codec_factory.modes[i].enabled = enabled;
375 return PJ_SUCCESS;
376 }
377 }
378
379 /* Mode not found in modes table, this may be a request to enable
380 * a non-standard G722.1 mode.
381 */
382
383 /* Non-standard mode need to be initialized first before user
384 * can disable it.
385 */
386 if (!enabled)
387 return PJ_ENOTFOUND;
388
389 /* Initialize a non-standard mode, look for available space. */
390 for (i = codec_factory.mode_rsv_start;
391 i < codec_factory.mode_count; ++i)
392 {
393 if (!codec_factory.modes[i].enabled)
394 {
395 codec_mode *mode = &codec_factory.modes[i];
396 mode->enabled = PJ_TRUE;
397 mode->sample_rate = sample_rate;
398 mode->bitrate = bitrate;
399 pj_utoa(mode->bitrate, mode->bitrate_str);
400
401 return PJ_SUCCESS;
402 }
403 }
404
405 /* No space for non-standard mode. */
406 return PJ_ETOOMANY;
407}
408
409
410/*
411 * Unregister G722.1 codec factory from pjmedia endpoint.
412 */
413PJ_DEF(pj_status_t) pjmedia_codec_g7221_deinit(void)
414{
415 pjmedia_codec_mgr *codec_mgr;
416 pj_status_t status;
417
418 if (codec_factory.pool == NULL) {
419 /* Already deinitialized */
420 return PJ_SUCCESS;
421 }
422
423 pj_mutex_lock(codec_factory.mutex);
424
425 /* Get the codec manager. */
426 codec_mgr = pjmedia_endpt_get_codec_mgr(codec_factory.endpt);
427 if (!codec_mgr) {
428 pj_pool_release(codec_factory.pool);
429 codec_factory.pool = NULL;
430 return PJ_EINVALIDOP;
431 }
432
433 /* Unregister G722.1 codec factory. */
434 status = pjmedia_codec_mgr_unregister_factory(codec_mgr,
435 &codec_factory.base);
436
437 /* Destroy mutex. */
438 pj_mutex_destroy(codec_factory.mutex);
439
440 /* Destroy pool. */
441 pj_pool_release(codec_factory.pool);
442 codec_factory.pool = NULL;
443
444 return status;
445}
446
447/*
448 * Check if factory can allocate the specified codec.
449 */
450static pj_status_t test_alloc( pjmedia_codec_factory *factory,
451 const pjmedia_codec_info *info )
452{
453 PJ_UNUSED_ARG(factory);
454
455 /* Type MUST be audio. */
456 if (info->type != PJMEDIA_TYPE_AUDIO)
457 return PJMEDIA_CODEC_EUNSUP;
458
459 /* Check encoding name. */
460 if (pj_stricmp2(&info->encoding_name, CODEC_TAG) != 0)
461 return PJMEDIA_CODEC_EUNSUP;
462
463 /* Check clock-rate */
464 if (info->clock_rate != WB_SAMPLE_RATE &&
465 info->clock_rate != UWB_SAMPLE_RATE)
466 {
467 return PJMEDIA_CODEC_EUNSUP;
468 }
469
470 return PJ_SUCCESS;
471}
472
473/*
474 * Generate default attribute.
475 */
476static pj_status_t default_attr ( pjmedia_codec_factory *factory,
477 const pjmedia_codec_info *id,
478 pjmedia_codec_param *attr )
479{
480 codec_mode *mode;
481
482 PJ_ASSERT_RETURN(factory==&codec_factory.base, PJ_EINVAL);
483
484 pj_bzero(attr, sizeof(pjmedia_codec_param));
485
486 mode = lookup_mode(id->pt);
487 if (mode == NULL || !mode->enabled)
488 return PJMEDIA_CODEC_EUNSUP;
489
490 attr->info.pt = (pj_uint8_t)id->pt;
491 attr->info.channel_cnt = 1;
492 attr->info.clock_rate = mode->sample_rate;
493 attr->info.max_bps = mode->bitrate;
494 attr->info.avg_bps = mode->bitrate;
495 attr->info.pcm_bits_per_sample = 16;
496 attr->info.frm_ptime = 20;
497
498 /* Default flags. */
499 attr->setting.plc = 1;
500 attr->setting.vad = 0;
501 attr->setting.frm_per_pkt = 1;
502
503 /* Default FMTP setting */
504 attr->setting.dec_fmtp.cnt = 1;
505 attr->setting.dec_fmtp.param[0].name = pj_str("bitrate");
506 attr->setting.dec_fmtp.param[0].val = pj_str(mode->bitrate_str);
507
508 return PJ_SUCCESS;
509}
510
511/*
512 * Enum codecs supported by this factory.
513 */
514static pj_status_t enum_codecs( pjmedia_codec_factory *factory,
515 unsigned *count,
516 pjmedia_codec_info codecs[])
517{
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000518 unsigned i, max_cnt;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000519
520 PJ_ASSERT_RETURN(factory==&codec_factory.base, PJ_EINVAL);
521 PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);
522
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000523 max_cnt = *count;
524 *count = 0;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000525
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000526 for (i=0; (i < codec_factory.mode_count) && (*count < max_cnt); ++i)
527 {
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000528 if (!codec_factory.modes[i].enabled)
529 continue;
530
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000531 pj_bzero(&codecs[*count], sizeof(pjmedia_codec_info));
532 codecs[*count].encoding_name = pj_str((char*)CODEC_TAG);
533 codecs[*count].pt = codec_factory.modes[i].pt;
534 codecs[*count].type = PJMEDIA_TYPE_AUDIO;
535 codecs[*count].clock_rate = codec_factory.modes[i].sample_rate;
536 codecs[*count].channel_cnt = 1;
537
538 ++ *count;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000539 }
540
541 return PJ_SUCCESS;
542}
543
544/*
545 * Allocate a new codec instance.
546 */
547static pj_status_t alloc_codec( pjmedia_codec_factory *factory,
548 const pjmedia_codec_info *id,
549 pjmedia_codec **p_codec)
550{
551 codec_private_t *codec_data;
552 pjmedia_codec *codec;
553 pj_pool_t *pool;
554 pj_status_t status;
555
556 PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);
557 PJ_ASSERT_RETURN(factory == &codec_factory.base, PJ_EINVAL);
558
559 pj_mutex_lock(codec_factory.mutex);
560
561 /* Create pool for codec instance */
562 pool = pjmedia_endpt_create_pool(codec_factory.endpt, "G7221", 512, 512);
563 codec = PJ_POOL_ZALLOC_T(pool, pjmedia_codec);
564 codec->op = &codec_op;
565 codec->factory = factory;
566 codec->codec_data = PJ_POOL_ZALLOC_T(pool, codec_private_t);
567 codec_data = (codec_private_t*) codec->codec_data;
568 codec_data->pool = pool;
569
570 /* Create silence detector */
571 status = pjmedia_silence_det_create(pool, id->clock_rate,
572 id->clock_rate * 20 / 1000,
573 &codec_data->vad);
574 if (status != PJ_SUCCESS) {
575 pj_mutex_unlock(codec_factory.mutex);
576 return status;
577 }
578
579 pj_mutex_unlock(codec_factory.mutex);
580
581 *p_codec = codec;
582 return PJ_SUCCESS;
583}
584
585/*
586 * Free codec.
587 */
588static pj_status_t dealloc_codec( pjmedia_codec_factory *factory,
589 pjmedia_codec *codec )
590{
591 codec_private_t *codec_data;
592 pj_pool_t *pool;
593
594 PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);
595 PJ_ASSERT_RETURN(factory == &codec_factory.base, PJ_EINVAL);
596
597 /* Close codec, if it's not closed. */
598 codec_data = (codec_private_t*) codec->codec_data;
599 pool = codec_data->pool;
600 codec_close(codec);
601
602 /* Release codec pool */
603 pj_pool_release(pool);
604
605 return PJ_SUCCESS;
606}
607
608/*
609 * Init codec.
610 */
611static pj_status_t codec_init( pjmedia_codec *codec,
612 pj_pool_t *pool )
613{
614 PJ_UNUSED_ARG(codec);
615 PJ_UNUSED_ARG(pool);
616 return PJ_SUCCESS;
617}
618
619/*
620 * Open codec.
621 */
622static pj_status_t codec_open( pjmedia_codec *codec,
623 pjmedia_codec_param *attr )
624{
625 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
626 pj_pool_t *pool;
627 unsigned tmp;
628
629 /* Validation mode first! */
630 if (!validate_mode(attr->info.clock_rate, attr->info.avg_bps))
631 return PJMEDIA_CODEC_EINMODE;
632
633 pool = codec_data->pool;
634
635 /* Initialize common state */
636 codec_data->vad_enabled = (attr->setting.vad != 0);
637 codec_data->plc_enabled = (attr->setting.plc != 0);
638
639 codec_data->bitrate = (pj_uint16_t)attr->info.avg_bps;
640 codec_data->frame_size_bits = (pj_uint16_t)(attr->info.avg_bps*20/1000);
641 codec_data->frame_size = (pj_uint16_t)(codec_data->frame_size_bits>>3);
642 codec_data->samples_per_frame = (pj_uint16_t)
643 (attr->info.clock_rate*20/1000);
644 codec_data->number_of_regions = (pj_uint16_t)
645 (attr->info.clock_rate <= WB_SAMPLE_RATE?
646 NUMBER_OF_REGIONS:MAX_NUMBER_OF_REGIONS);
647
648 /* Initialize encoder state */
649 tmp = codec_data->samples_per_frame << 1;
650 codec_data->enc_old_frame = (Word16*)pj_pool_zalloc(pool, tmp);
651
652 /* Initialize decoder state */
653 tmp = codec_data->samples_per_frame;
654 codec_data->dec_old_frame = (Word16*)pj_pool_zalloc(pool, tmp);
655
656 tmp = codec_data->samples_per_frame << 1;
657 codec_data->dec_old_mlt_coefs = (Word16*)pj_pool_zalloc(pool, tmp);
658
659 codec_data->dec_randobj.seed0 = 1;
660 codec_data->dec_randobj.seed1 = 1;
661 codec_data->dec_randobj.seed2 = 1;
662 codec_data->dec_randobj.seed3 = 1;
663
664 return PJ_SUCCESS;
665}
666
667/*
668 * Close codec.
669 */
670static pj_status_t codec_close( pjmedia_codec *codec )
671{
672 PJ_UNUSED_ARG(codec);
673
674 return PJ_SUCCESS;
675}
676
677
678/*
679 * Modify codec settings.
680 */
681static pj_status_t codec_modify( pjmedia_codec *codec,
682 const pjmedia_codec_param *attr )
683{
684 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
685
686 codec_data->vad_enabled = (attr->setting.vad != 0);
687 codec_data->plc_enabled = (attr->setting.plc != 0);
688
689 return PJ_SUCCESS;
690}
691
692/*
693 * Get frames in the packet.
694 */
695static pj_status_t codec_parse( pjmedia_codec *codec,
696 void *pkt,
697 pj_size_t pkt_size,
698 const pj_timestamp *ts,
699 unsigned *frame_cnt,
700 pjmedia_frame frames[])
701{
702 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
703 unsigned count = 0;
704
705 PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);
706
707 /* Parse based on fixed frame size. */
708 while (pkt_size >= codec_data->frame_size && count < *frame_cnt) {
709 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;
710 frames[count].buf = pkt;
711 frames[count].size = codec_data->frame_size;
712 frames[count].timestamp.u64 = ts->u64 +
713 count * codec_data->samples_per_frame;
714
715 pkt = (pj_uint8_t*)pkt + codec_data->frame_size;
716 pkt_size -= codec_data->frame_size;
717
718 ++count;
719 }
720
721 pj_assert(pkt_size == 0);
722 *frame_cnt = count;
723
724 return PJ_SUCCESS;
725}
726
727/*
728 * Encode frames.
729 */
730static pj_status_t codec_encode( pjmedia_codec *codec,
731 const struct pjmedia_frame *input,
732 unsigned output_buf_len,
733 struct pjmedia_frame *output)
734{
735 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
736 Word16 mlt_coefs[MAX_SAMPLES_PER_FRAME];
737 Word16 mag_shift;
738
739 /* Check frame in & out size */
740 PJ_ASSERT_RETURN((pj_uint16_t)input->size ==
741 (codec_data->samples_per_frame<<1),
742 PJMEDIA_CODEC_EPCMTOOSHORT);
743 PJ_ASSERT_RETURN(output_buf_len >= codec_data->frame_size,
744 PJMEDIA_CODEC_EFRMTOOSHORT);
745
746 /* Apply silence detection if VAD is enabled */
747 if (codec_data->vad_enabled) {
748 pj_bool_t is_silence;
749 pj_int32_t silence_duration;
750
751 pj_assert(codec_data->vad);
752
753 silence_duration = pj_timestamp_diff32(&codec_data->last_tx,
754 &input->timestamp);
755
756 is_silence = pjmedia_silence_det_detect(codec_data->vad,
757 (const pj_int16_t*) input->buf,
758 (input->size >> 1),
759 NULL);
760 if (is_silence &&
761 PJMEDIA_CODEC_MAX_SILENCE_PERIOD != -1 &&
762 silence_duration < (PJMEDIA_CODEC_MAX_SILENCE_PERIOD *
763 (int)codec_data->samples_per_frame / 20))
764 {
765 output->type = PJMEDIA_FRAME_TYPE_NONE;
766 output->buf = NULL;
767 output->size = 0;
768 output->timestamp = input->timestamp;
769 return PJ_SUCCESS;
770 } else {
771 codec_data->last_tx = input->timestamp;
772 }
773 }
774
775 /* Convert input samples to rmlt coefs */
776 mag_shift = samples_to_rmlt_coefs((Word16*)input->buf,
777 codec_data->enc_old_frame,
778 mlt_coefs,
779 codec_data->samples_per_frame);
780
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000781 /* Encode the mlt coefs. Note that encoder output stream is 16 bit array,
782 * so we need to take care about endianness.
783 */
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000784 encoder(codec_data->frame_size_bits,
785 codec_data->number_of_regions,
786 mlt_coefs,
787 mag_shift,
788 output->buf);
789
Benny Prijono3594ab32009-04-18 14:29:28 +0000790 /* Encoder output are in native host byte order, while ITU says
791 * it must be in network byte order (MSB first).
792 */
793 swap_bytes((pj_uint16_t*)output->buf, codec_data->frame_size/2);
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000794
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000795 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
796 output->size = codec_data->frame_size;
797
798 return PJ_SUCCESS;
799}
800
801/*
802 * Decode frame.
803 */
804static pj_status_t codec_decode( pjmedia_codec *codec,
805 const struct pjmedia_frame *input,
806 unsigned output_buf_len,
807 struct pjmedia_frame *output)
808{
809 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
810 Word16 mlt_coefs[MAX_SAMPLES_PER_FRAME];
811 Word16 mag_shift;
812 Bit_Obj bitobj;
813 Word16 frame_error_flag = 0;
814
815 /* Check frame out length size */
816 PJ_ASSERT_RETURN(output_buf_len >=
817 (unsigned)(codec_data->samples_per_frame<<1),
818 PJMEDIA_CODEC_EPCMTOOSHORT);
819
820 /* If input is NULL, perform PLC by settting frame_error_flag to 1 */
821 if (input) {
822 /* Check frame in length size */
823 PJ_ASSERT_RETURN((pj_uint16_t)input->size == codec_data->frame_size,
824 PJMEDIA_CODEC_EFRMINLEN);
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000825
Benny Prijono3594ab32009-04-18 14:29:28 +0000826 /* Decoder requires input of 16-bits array in native host byte
827 * order, while the frame received from the network are in
828 * network byte order (MSB first).
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000829 */
Benny Prijono3594ab32009-04-18 14:29:28 +0000830 swap_bytes((pj_uint16_t*)input->buf, codec_data->frame_size/2);
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000831
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000832 bitobj.code_word_ptr = (Word16*)input->buf;
833 bitobj.current_word = *bitobj.code_word_ptr;
834 bitobj.code_bit_count = 0;
835 bitobj.number_of_bits_left = codec_data->frame_size_bits;
836 } else {
837 pj_bzero(&bitobj, sizeof(bitobj));
838 frame_error_flag = 1;
839 }
840
841 /* Process the input frame to get mlt coefs */
842 decoder(&bitobj,
843 &codec_data->dec_randobj,
844 codec_data->number_of_regions,
845 mlt_coefs,
846 &mag_shift,
847 &codec_data->dec_old_mag_shift,
848 codec_data->dec_old_mlt_coefs,
849 frame_error_flag);
850
851 /* Convert the mlt_coefs to PCM samples */
852 rmlt_coefs_to_samples(mlt_coefs,
853 codec_data->dec_old_frame,
854 (Word16*)output->buf,
855 codec_data->samples_per_frame,
856 mag_shift);
857
858 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
859 output->size = codec_data->samples_per_frame << 1;
860
861 return PJ_SUCCESS;
862}
863
864/*
865 * Recover lost frame.
866 */
867static pj_status_t codec_recover( pjmedia_codec *codec,
868 unsigned output_buf_len,
869 struct pjmedia_frame *output)
870{
871 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
872
873 /* Use native PLC when PLC is enabled. */
874 if (codec_data->plc_enabled)
875 return codec_decode(codec, NULL, output_buf_len, output);
876
877 /* Otherwise just return zero-fill frame. */
878 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
879 output->size = codec_data->samples_per_frame << 1;
880
881 pjmedia_zero_samples((pj_int16_t*)output->buf,
882 codec_data->samples_per_frame);
883
884 return PJ_SUCCESS;
885}
886
887#endif /* PJMEDIA_HAS_G7221_CODEC */