blob: fcaebde21111ae9fd97ac21340d52d97e3d9160b [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
Benny Prijono8496b932009-04-20 14:19:11 +0000140 int pcm_shift; /**< Level adjustment */
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000141 unsigned mode_count; /**< Number of G722.1 modes. */
142 codec_mode modes[MAX_CODEC_MODES]; /**< The G722.1 modes. */
143 unsigned mode_rsv_start;/**< Start index of G722.1 non-
144 standard modes, currently
145 there can only be up to two
146 non-standard modes enabled
147 at the same time. */
148} codec_factory;
149
150/* G722.1 codec private data. */
151typedef struct codec_private {
152 pj_pool_t *pool; /**< Pool for each instance. */
153 pj_bool_t plc_enabled; /**< PLC enabled? */
154 pj_bool_t vad_enabled; /**< VAD enabled? */
155 pjmedia_silence_det *vad; /**< PJMEDIA VAD instance. */
156 pj_timestamp last_tx; /**< Timestamp of last transmit.*/
157
158 /* ITU ref implementation seems to leave the codec engine states to be
159 * managed by the application, so here we go.
160 */
161
162 /* Common engine state */
163 pj_uint16_t samples_per_frame; /**< Samples per frame. */
164 pj_uint16_t bitrate; /**< Coded stream bitrate. */
165 pj_uint16_t frame_size; /**< Coded frame size. */
166 pj_uint16_t frame_size_bits; /**< Coded frame size in bits. */
167 pj_uint16_t number_of_regions; /**< Number of regions. */
Benny Prijono8496b932009-04-20 14:19:11 +0000168 int pcm_shift; /**< Adjustment for PCM in/out */
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000169
170 /* Encoder specific state */
Benny Prijono8496b932009-04-20 14:19:11 +0000171 Word16 *enc_frame; /**< 16bit to 14bit buffer */
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000172 Word16 *enc_old_frame;
173
174 /* Decoder specific state */
175 Word16 *dec_old_frame;
176 Rand_Obj dec_randobj;
177 Word16 dec_old_mag_shift;
178 Word16 *dec_old_mlt_coefs;
179} codec_private_t;
180
181/*
182 * Helper function for looking up mode based on payload type.
183 */
184static codec_mode* lookup_mode(unsigned pt)
185{
186 codec_mode* mode = NULL;
187 unsigned i;
188
189 for (i = 0; i < codec_factory.mode_count; ++i) {
190 mode = &codec_factory.modes[i];
191 if (mode->pt == pt)
192 break;
193 }
194
195 return mode;
196}
197
198/*
199 * Helper function to validate G722.1 mode. Valid modes are defined as:
200 * 1. sample rate must be 16kHz or 32kHz,
201 * 2. bitrate:
202 * - for sampling rate 16kHz: 16000 to 32000 bps, it must be a multiple
203 * of 400 (to keep RTP payload octed-aligned)
204 * - for sampling rate 32kHz: 24000 to 48000 bps, it must be a multiple
205 * of 400 (to keep RTP payload octed-aligned)
206 */
207static pj_bool_t validate_mode(unsigned sample_rate, unsigned bitrate)
208{
209 if (sample_rate == WB_SAMPLE_RATE) {
210 if (bitrate < 16000 || bitrate > 32000 ||
211 ((bitrate-16000) % 400 != 0))
212 {
213 return PJ_FALSE;
214 }
215 } else if (sample_rate == UWB_SAMPLE_RATE) {
216 if (bitrate < 24000 || bitrate > 48000 ||
217 ((bitrate-24000) % 400 != 0))
218 {
219 return PJ_FALSE;
220 }
221 } else {
222 return PJ_FALSE;
223 }
224
225 return PJ_TRUE;
226}
227
Benny Prijono3594ab32009-04-18 14:29:28 +0000228#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
229PJ_INLINE(void) swap_bytes(pj_uint16_t *buf, unsigned count)
230{
231 pj_uint16_t *end = buf + count;
232 while (buf != end) {
233 *buf = (pj_uint16_t)((*buf << 8) | (*buf >> 8));
234 ++buf;
235 }
236}
237#else
238#define swap_bytes(buf, count)
239#endif
240
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000241/*
242 * Initialize and register G722.1 codec factory to pjmedia endpoint.
243 */
244PJ_DEF(pj_status_t) pjmedia_codec_g7221_init( pjmedia_endpt *endpt )
245{
246 pjmedia_codec_mgr *codec_mgr;
247 codec_mode *mode;
248 pj_status_t status;
249
250 if (codec_factory.pool != NULL) {
251 /* Already initialized. */
252 return PJ_SUCCESS;
253 }
254
255 /* Initialize codec modes, by default all standard bitrates are enabled */
Nanang Izzuddin27659812009-04-15 17:50:50 +0000256 codec_factory.mode_count = 0;
Benny Prijono8496b932009-04-20 14:19:11 +0000257 codec_factory.pcm_shift = PJMEDIA_G7221_DEFAULT_PCM_SHIFT;
Nanang Izzuddin27659812009-04-15 17:50:50 +0000258
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000259 mode = &codec_factory.modes[codec_factory.mode_count++];
260 mode->enabled = PJ_TRUE;
261 mode->pt = PJMEDIA_RTP_PT_G722_1_24;
262 mode->sample_rate = WB_SAMPLE_RATE;
263 mode->bitrate = 24000;
264 pj_utoa(mode->bitrate, mode->bitrate_str);
265
266 mode = &codec_factory.modes[codec_factory.mode_count++];
267 mode->enabled = PJ_TRUE;
268 mode->pt = PJMEDIA_RTP_PT_G722_1_32;
269 mode->sample_rate = WB_SAMPLE_RATE;
270 mode->bitrate = 32000;
271 pj_utoa(mode->bitrate, mode->bitrate_str);
272
273 mode = &codec_factory.modes[codec_factory.mode_count++];
274 mode->enabled = PJ_TRUE;
275 mode->pt = PJMEDIA_RTP_PT_G7221C_24;
276 mode->sample_rate = UWB_SAMPLE_RATE;
277 mode->bitrate = 24000;
278 pj_utoa(mode->bitrate, mode->bitrate_str);
279
280 mode = &codec_factory.modes[codec_factory.mode_count++];
281 mode->enabled = PJ_TRUE;
282 mode->pt = PJMEDIA_RTP_PT_G7221C_32;
283 mode->sample_rate = UWB_SAMPLE_RATE;
284 mode->bitrate = 32000;
285 pj_utoa(mode->bitrate, mode->bitrate_str);
286
287 mode = &codec_factory.modes[codec_factory.mode_count++];
288 mode->enabled = PJ_TRUE;
289 mode->pt = PJMEDIA_RTP_PT_G7221C_48;
290 mode->sample_rate = UWB_SAMPLE_RATE;
291 mode->bitrate = 48000;
292 pj_utoa(mode->bitrate, mode->bitrate_str);
293
294 /* Non-standard bitrates */
295
296 /* Bitrate 16kbps is non-standard but rather commonly used. */
297 mode = &codec_factory.modes[codec_factory.mode_count++];
298 mode->enabled = PJ_FALSE;
299 mode->pt = PJMEDIA_RTP_PT_G722_1_16;
300 mode->sample_rate = WB_SAMPLE_RATE;
301 mode->bitrate = 16000;
302 pj_utoa(mode->bitrate, mode->bitrate_str);
303
304 /* Reserved two modes for non-standard bitrates */
305 codec_factory.mode_rsv_start = codec_factory.mode_count;
306 mode = &codec_factory.modes[codec_factory.mode_count++];
307 mode->enabled = PJ_FALSE;
308 mode->pt = PJMEDIA_RTP_PT_G7221_RSV1;
309
310 mode = &codec_factory.modes[codec_factory.mode_count++];
311 mode->enabled = PJ_FALSE;
312 mode->pt = PJMEDIA_RTP_PT_G7221_RSV2;
313
314 pj_assert(codec_factory.mode_count <= MAX_CODEC_MODES);
315
316 /* Create G722.1 codec factory. */
317 codec_factory.base.op = &codec_factory_op;
318 codec_factory.base.factory_data = NULL;
319 codec_factory.endpt = endpt;
320
321 codec_factory.pool = pjmedia_endpt_create_pool(endpt, "G722.1 codec",
322 4000, 4000);
323 if (!codec_factory.pool)
324 return PJ_ENOMEM;
325
326 /* Create mutex. */
327 status = pj_mutex_create_simple(codec_factory.pool, "G722.1 codec",
328 &codec_factory.mutex);
329 if (status != PJ_SUCCESS)
330 goto on_error;
331
332 /* Get the codec manager. */
333 codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);
334 if (!codec_mgr) {
335 status = PJ_EINVALIDOP;
336 goto on_error;
337 }
338
339 /* Register codec factory to endpoint. */
340 status = pjmedia_codec_mgr_register_factory(codec_mgr,
341 &codec_factory.base);
342 if (status != PJ_SUCCESS)
343 goto on_error;
344
345 /* Done. */
346 return PJ_SUCCESS;
347
348on_error:
349 if (codec_factory.mutex) {
350 pj_mutex_destroy(codec_factory.mutex);
351 codec_factory.mutex = NULL;
352 }
353
354 pj_pool_release(codec_factory.pool);
355 codec_factory.pool = NULL;
356 return status;
357}
358
359
360/**
361 * Enable and disable G722.1 modes, including non-standard modes.
362 */
363PJ_DEF(pj_status_t) pjmedia_codec_g7221_set_mode(unsigned sample_rate,
364 unsigned bitrate,
365 pj_bool_t enabled)
366{
367 unsigned i;
368
369 /* Validate mode */
370 if (!validate_mode(sample_rate, bitrate))
371 return PJMEDIA_CODEC_EINMODE;
372
373 /* Look up in factory modes table */
374 for (i = 0; i < codec_factory.mode_count; ++i) {
375 if (codec_factory.modes[i].sample_rate == sample_rate &&
376 codec_factory.modes[i].bitrate == bitrate)
377 {
378 codec_factory.modes[i].enabled = enabled;
379 return PJ_SUCCESS;
380 }
381 }
382
383 /* Mode not found in modes table, this may be a request to enable
384 * a non-standard G722.1 mode.
385 */
386
387 /* Non-standard mode need to be initialized first before user
388 * can disable it.
389 */
390 if (!enabled)
391 return PJ_ENOTFOUND;
392
393 /* Initialize a non-standard mode, look for available space. */
394 for (i = codec_factory.mode_rsv_start;
395 i < codec_factory.mode_count; ++i)
396 {
397 if (!codec_factory.modes[i].enabled)
398 {
399 codec_mode *mode = &codec_factory.modes[i];
400 mode->enabled = PJ_TRUE;
401 mode->sample_rate = sample_rate;
402 mode->bitrate = bitrate;
403 pj_utoa(mode->bitrate, mode->bitrate_str);
404
405 return PJ_SUCCESS;
406 }
407 }
408
409 /* No space for non-standard mode. */
410 return PJ_ETOOMANY;
411}
412
413
414/*
Benny Prijono8496b932009-04-20 14:19:11 +0000415 * Set level adjustment.
416 */
417PJ_DEF(pj_status_t) pjmedia_codec_g7221_set_pcm_shift(int val)
418{
419 codec_factory.pcm_shift = val;
420 return PJ_SUCCESS;
421}
422
423/*
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000424 * Unregister G722.1 codec factory from pjmedia endpoint.
425 */
426PJ_DEF(pj_status_t) pjmedia_codec_g7221_deinit(void)
427{
428 pjmedia_codec_mgr *codec_mgr;
429 pj_status_t status;
430
431 if (codec_factory.pool == NULL) {
432 /* Already deinitialized */
433 return PJ_SUCCESS;
434 }
435
436 pj_mutex_lock(codec_factory.mutex);
437
438 /* Get the codec manager. */
439 codec_mgr = pjmedia_endpt_get_codec_mgr(codec_factory.endpt);
440 if (!codec_mgr) {
441 pj_pool_release(codec_factory.pool);
442 codec_factory.pool = NULL;
443 return PJ_EINVALIDOP;
444 }
445
446 /* Unregister G722.1 codec factory. */
447 status = pjmedia_codec_mgr_unregister_factory(codec_mgr,
448 &codec_factory.base);
449
450 /* Destroy mutex. */
451 pj_mutex_destroy(codec_factory.mutex);
452
453 /* Destroy pool. */
454 pj_pool_release(codec_factory.pool);
455 codec_factory.pool = NULL;
456
457 return status;
458}
459
460/*
461 * Check if factory can allocate the specified codec.
462 */
463static pj_status_t test_alloc( pjmedia_codec_factory *factory,
464 const pjmedia_codec_info *info )
465{
466 PJ_UNUSED_ARG(factory);
467
468 /* Type MUST be audio. */
469 if (info->type != PJMEDIA_TYPE_AUDIO)
470 return PJMEDIA_CODEC_EUNSUP;
471
472 /* Check encoding name. */
473 if (pj_stricmp2(&info->encoding_name, CODEC_TAG) != 0)
474 return PJMEDIA_CODEC_EUNSUP;
475
476 /* Check clock-rate */
477 if (info->clock_rate != WB_SAMPLE_RATE &&
478 info->clock_rate != UWB_SAMPLE_RATE)
479 {
480 return PJMEDIA_CODEC_EUNSUP;
481 }
482
483 return PJ_SUCCESS;
484}
485
486/*
487 * Generate default attribute.
488 */
489static pj_status_t default_attr ( pjmedia_codec_factory *factory,
490 const pjmedia_codec_info *id,
491 pjmedia_codec_param *attr )
492{
493 codec_mode *mode;
494
495 PJ_ASSERT_RETURN(factory==&codec_factory.base, PJ_EINVAL);
496
497 pj_bzero(attr, sizeof(pjmedia_codec_param));
498
499 mode = lookup_mode(id->pt);
500 if (mode == NULL || !mode->enabled)
501 return PJMEDIA_CODEC_EUNSUP;
502
503 attr->info.pt = (pj_uint8_t)id->pt;
504 attr->info.channel_cnt = 1;
505 attr->info.clock_rate = mode->sample_rate;
506 attr->info.max_bps = mode->bitrate;
507 attr->info.avg_bps = mode->bitrate;
508 attr->info.pcm_bits_per_sample = 16;
509 attr->info.frm_ptime = 20;
510
511 /* Default flags. */
512 attr->setting.plc = 1;
513 attr->setting.vad = 0;
514 attr->setting.frm_per_pkt = 1;
515
516 /* Default FMTP setting */
517 attr->setting.dec_fmtp.cnt = 1;
518 attr->setting.dec_fmtp.param[0].name = pj_str("bitrate");
519 attr->setting.dec_fmtp.param[0].val = pj_str(mode->bitrate_str);
520
521 return PJ_SUCCESS;
522}
523
524/*
525 * Enum codecs supported by this factory.
526 */
527static pj_status_t enum_codecs( pjmedia_codec_factory *factory,
528 unsigned *count,
529 pjmedia_codec_info codecs[])
530{
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000531 unsigned i, max_cnt;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000532
533 PJ_ASSERT_RETURN(factory==&codec_factory.base, PJ_EINVAL);
534 PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);
535
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000536 max_cnt = *count;
537 *count = 0;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000538
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000539 for (i=0; (i < codec_factory.mode_count) && (*count < max_cnt); ++i)
540 {
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000541 if (!codec_factory.modes[i].enabled)
542 continue;
543
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000544 pj_bzero(&codecs[*count], sizeof(pjmedia_codec_info));
545 codecs[*count].encoding_name = pj_str((char*)CODEC_TAG);
546 codecs[*count].pt = codec_factory.modes[i].pt;
547 codecs[*count].type = PJMEDIA_TYPE_AUDIO;
548 codecs[*count].clock_rate = codec_factory.modes[i].sample_rate;
549 codecs[*count].channel_cnt = 1;
550
551 ++ *count;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000552 }
553
554 return PJ_SUCCESS;
555}
556
557/*
558 * Allocate a new codec instance.
559 */
560static pj_status_t alloc_codec( pjmedia_codec_factory *factory,
561 const pjmedia_codec_info *id,
562 pjmedia_codec **p_codec)
563{
564 codec_private_t *codec_data;
565 pjmedia_codec *codec;
566 pj_pool_t *pool;
567 pj_status_t status;
568
569 PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);
570 PJ_ASSERT_RETURN(factory == &codec_factory.base, PJ_EINVAL);
571
572 pj_mutex_lock(codec_factory.mutex);
573
574 /* Create pool for codec instance */
575 pool = pjmedia_endpt_create_pool(codec_factory.endpt, "G7221", 512, 512);
576 codec = PJ_POOL_ZALLOC_T(pool, pjmedia_codec);
577 codec->op = &codec_op;
578 codec->factory = factory;
579 codec->codec_data = PJ_POOL_ZALLOC_T(pool, codec_private_t);
580 codec_data = (codec_private_t*) codec->codec_data;
581 codec_data->pool = pool;
582
583 /* Create silence detector */
584 status = pjmedia_silence_det_create(pool, id->clock_rate,
585 id->clock_rate * 20 / 1000,
586 &codec_data->vad);
587 if (status != PJ_SUCCESS) {
588 pj_mutex_unlock(codec_factory.mutex);
589 return status;
590 }
591
592 pj_mutex_unlock(codec_factory.mutex);
593
594 *p_codec = codec;
595 return PJ_SUCCESS;
596}
597
598/*
599 * Free codec.
600 */
601static pj_status_t dealloc_codec( pjmedia_codec_factory *factory,
602 pjmedia_codec *codec )
603{
604 codec_private_t *codec_data;
605 pj_pool_t *pool;
606
607 PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);
608 PJ_ASSERT_RETURN(factory == &codec_factory.base, PJ_EINVAL);
609
610 /* Close codec, if it's not closed. */
611 codec_data = (codec_private_t*) codec->codec_data;
612 pool = codec_data->pool;
613 codec_close(codec);
614
615 /* Release codec pool */
616 pj_pool_release(pool);
617
618 return PJ_SUCCESS;
619}
620
621/*
622 * Init codec.
623 */
624static pj_status_t codec_init( pjmedia_codec *codec,
625 pj_pool_t *pool )
626{
627 PJ_UNUSED_ARG(codec);
628 PJ_UNUSED_ARG(pool);
629 return PJ_SUCCESS;
630}
631
632/*
633 * Open codec.
634 */
635static pj_status_t codec_open( pjmedia_codec *codec,
636 pjmedia_codec_param *attr )
637{
638 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
639 pj_pool_t *pool;
640 unsigned tmp;
641
642 /* Validation mode first! */
643 if (!validate_mode(attr->info.clock_rate, attr->info.avg_bps))
644 return PJMEDIA_CODEC_EINMODE;
645
646 pool = codec_data->pool;
647
648 /* Initialize common state */
649 codec_data->vad_enabled = (attr->setting.vad != 0);
650 codec_data->plc_enabled = (attr->setting.plc != 0);
651
652 codec_data->bitrate = (pj_uint16_t)attr->info.avg_bps;
653 codec_data->frame_size_bits = (pj_uint16_t)(attr->info.avg_bps*20/1000);
654 codec_data->frame_size = (pj_uint16_t)(codec_data->frame_size_bits>>3);
655 codec_data->samples_per_frame = (pj_uint16_t)
656 (attr->info.clock_rate*20/1000);
657 codec_data->number_of_regions = (pj_uint16_t)
658 (attr->info.clock_rate <= WB_SAMPLE_RATE?
659 NUMBER_OF_REGIONS:MAX_NUMBER_OF_REGIONS);
Benny Prijono8496b932009-04-20 14:19:11 +0000660 codec_data->pcm_shift = codec_factory.pcm_shift;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000661
662 /* Initialize encoder state */
663 tmp = codec_data->samples_per_frame << 1;
664 codec_data->enc_old_frame = (Word16*)pj_pool_zalloc(pool, tmp);
Benny Prijono8496b932009-04-20 14:19:11 +0000665 codec_data->enc_frame = (Word16*)pj_pool_alloc(pool, tmp);
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000666
667 /* Initialize decoder state */
668 tmp = codec_data->samples_per_frame;
669 codec_data->dec_old_frame = (Word16*)pj_pool_zalloc(pool, tmp);
670
671 tmp = codec_data->samples_per_frame << 1;
672 codec_data->dec_old_mlt_coefs = (Word16*)pj_pool_zalloc(pool, tmp);
673
674 codec_data->dec_randobj.seed0 = 1;
675 codec_data->dec_randobj.seed1 = 1;
676 codec_data->dec_randobj.seed2 = 1;
677 codec_data->dec_randobj.seed3 = 1;
678
679 return PJ_SUCCESS;
680}
681
682/*
683 * Close codec.
684 */
685static pj_status_t codec_close( pjmedia_codec *codec )
686{
687 PJ_UNUSED_ARG(codec);
688
689 return PJ_SUCCESS;
690}
691
692
693/*
694 * Modify codec settings.
695 */
696static pj_status_t codec_modify( pjmedia_codec *codec,
697 const pjmedia_codec_param *attr )
698{
699 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
700
701 codec_data->vad_enabled = (attr->setting.vad != 0);
702 codec_data->plc_enabled = (attr->setting.plc != 0);
703
704 return PJ_SUCCESS;
705}
706
707/*
708 * Get frames in the packet.
709 */
710static pj_status_t codec_parse( pjmedia_codec *codec,
711 void *pkt,
712 pj_size_t pkt_size,
713 const pj_timestamp *ts,
714 unsigned *frame_cnt,
715 pjmedia_frame frames[])
716{
717 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
718 unsigned count = 0;
719
720 PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);
721
722 /* Parse based on fixed frame size. */
723 while (pkt_size >= codec_data->frame_size && count < *frame_cnt) {
724 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;
725 frames[count].buf = pkt;
726 frames[count].size = codec_data->frame_size;
727 frames[count].timestamp.u64 = ts->u64 +
728 count * codec_data->samples_per_frame;
729
730 pkt = (pj_uint8_t*)pkt + codec_data->frame_size;
731 pkt_size -= codec_data->frame_size;
732
733 ++count;
734 }
735
736 pj_assert(pkt_size == 0);
737 *frame_cnt = count;
738
739 return PJ_SUCCESS;
740}
741
742/*
743 * Encode frames.
744 */
745static pj_status_t codec_encode( pjmedia_codec *codec,
746 const struct pjmedia_frame *input,
747 unsigned output_buf_len,
748 struct pjmedia_frame *output)
749{
750 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
Benny Prijono8496b932009-04-20 14:19:11 +0000751 const Word16 *pcm_input;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000752 Word16 mlt_coefs[MAX_SAMPLES_PER_FRAME];
753 Word16 mag_shift;
754
755 /* Check frame in & out size */
756 PJ_ASSERT_RETURN((pj_uint16_t)input->size ==
757 (codec_data->samples_per_frame<<1),
758 PJMEDIA_CODEC_EPCMTOOSHORT);
759 PJ_ASSERT_RETURN(output_buf_len >= codec_data->frame_size,
760 PJMEDIA_CODEC_EFRMTOOSHORT);
761
762 /* Apply silence detection if VAD is enabled */
763 if (codec_data->vad_enabled) {
764 pj_bool_t is_silence;
765 pj_int32_t silence_duration;
766
767 pj_assert(codec_data->vad);
768
769 silence_duration = pj_timestamp_diff32(&codec_data->last_tx,
770 &input->timestamp);
771
772 is_silence = pjmedia_silence_det_detect(codec_data->vad,
773 (const pj_int16_t*) input->buf,
774 (input->size >> 1),
775 NULL);
776 if (is_silence &&
777 PJMEDIA_CODEC_MAX_SILENCE_PERIOD != -1 &&
778 silence_duration < (PJMEDIA_CODEC_MAX_SILENCE_PERIOD *
779 (int)codec_data->samples_per_frame / 20))
780 {
781 output->type = PJMEDIA_FRAME_TYPE_NONE;
782 output->buf = NULL;
783 output->size = 0;
784 output->timestamp = input->timestamp;
785 return PJ_SUCCESS;
786 } else {
787 codec_data->last_tx = input->timestamp;
788 }
789 }
790
Benny Prijono8496b932009-04-20 14:19:11 +0000791 /* Encoder adjust the input signal level */
792 if (codec_data->pcm_shift) {
793 unsigned i;
794 pcm_input = (const Word16*)input->buf;
795 for (i=0; i<codec_data->samples_per_frame; ++i) {
796 codec_data->enc_frame[i] =
797 (pj_int16_t)(pcm_input[i] >> codec_data->pcm_shift);
798 }
799 pcm_input = codec_data->enc_frame;
800 } else {
801 pcm_input = (const Word16*)input->buf;
802 }
803
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000804 /* Convert input samples to rmlt coefs */
Benny Prijono8496b932009-04-20 14:19:11 +0000805 mag_shift = samples_to_rmlt_coefs(pcm_input,
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000806 codec_data->enc_old_frame,
807 mlt_coefs,
808 codec_data->samples_per_frame);
809
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000810 /* Encode the mlt coefs. Note that encoder output stream is 16 bit array,
811 * so we need to take care about endianness.
812 */
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000813 encoder(codec_data->frame_size_bits,
814 codec_data->number_of_regions,
815 mlt_coefs,
816 mag_shift,
817 output->buf);
818
Benny Prijono3594ab32009-04-18 14:29:28 +0000819 /* Encoder output are in native host byte order, while ITU says
820 * it must be in network byte order (MSB first).
821 */
822 swap_bytes((pj_uint16_t*)output->buf, codec_data->frame_size/2);
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000823
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000824 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
825 output->size = codec_data->frame_size;
826
827 return PJ_SUCCESS;
828}
829
830/*
831 * Decode frame.
832 */
833static pj_status_t codec_decode( pjmedia_codec *codec,
834 const struct pjmedia_frame *input,
835 unsigned output_buf_len,
836 struct pjmedia_frame *output)
837{
838 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
839 Word16 mlt_coefs[MAX_SAMPLES_PER_FRAME];
840 Word16 mag_shift;
841 Bit_Obj bitobj;
842 Word16 frame_error_flag = 0;
843
844 /* Check frame out length size */
845 PJ_ASSERT_RETURN(output_buf_len >=
846 (unsigned)(codec_data->samples_per_frame<<1),
847 PJMEDIA_CODEC_EPCMTOOSHORT);
848
849 /* If input is NULL, perform PLC by settting frame_error_flag to 1 */
850 if (input) {
851 /* Check frame in length size */
852 PJ_ASSERT_RETURN((pj_uint16_t)input->size == codec_data->frame_size,
853 PJMEDIA_CODEC_EFRMINLEN);
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000854
Benny Prijono3594ab32009-04-18 14:29:28 +0000855 /* Decoder requires input of 16-bits array in native host byte
856 * order, while the frame received from the network are in
857 * network byte order (MSB first).
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000858 */
Benny Prijono3594ab32009-04-18 14:29:28 +0000859 swap_bytes((pj_uint16_t*)input->buf, codec_data->frame_size/2);
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000860
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000861 bitobj.code_word_ptr = (Word16*)input->buf;
862 bitobj.current_word = *bitobj.code_word_ptr;
863 bitobj.code_bit_count = 0;
864 bitobj.number_of_bits_left = codec_data->frame_size_bits;
865 } else {
866 pj_bzero(&bitobj, sizeof(bitobj));
867 frame_error_flag = 1;
868 }
869
870 /* Process the input frame to get mlt coefs */
871 decoder(&bitobj,
872 &codec_data->dec_randobj,
873 codec_data->number_of_regions,
874 mlt_coefs,
875 &mag_shift,
876 &codec_data->dec_old_mag_shift,
877 codec_data->dec_old_mlt_coefs,
878 frame_error_flag);
879
880 /* Convert the mlt_coefs to PCM samples */
881 rmlt_coefs_to_samples(mlt_coefs,
882 codec_data->dec_old_frame,
883 (Word16*)output->buf,
884 codec_data->samples_per_frame,
885 mag_shift);
886
Benny Prijono8496b932009-04-20 14:19:11 +0000887 /* Decoder adjust PCM signal */
888 if (codec_data->pcm_shift) {
889 unsigned i;
890 pj_int16_t *buf = (Word16*)output->buf;
891
892 for (i=0; i<codec_data->samples_per_frame; ++i) {
893 buf[i] <<= codec_data->pcm_shift;
894 }
895 }
896
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000897 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
898 output->size = codec_data->samples_per_frame << 1;
899
900 return PJ_SUCCESS;
901}
902
903/*
904 * Recover lost frame.
905 */
906static pj_status_t codec_recover( pjmedia_codec *codec,
907 unsigned output_buf_len,
908 struct pjmedia_frame *output)
909{
910 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
911
912 /* Use native PLC when PLC is enabled. */
913 if (codec_data->plc_enabled)
914 return codec_decode(codec, NULL, output_buf_len, output);
915
916 /* Otherwise just return zero-fill frame. */
917 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
918 output->size = codec_data->samples_per_frame << 1;
919
920 pjmedia_zero_samples((pj_int16_t*)output->buf,
921 codec_data->samples_per_frame);
922
923 return PJ_SUCCESS;
924}
925
926#endif /* PJMEDIA_HAS_G7221_CODEC */