blob: c5f81211fe4813d32b1b805aa0f54694d303eb29 [file] [log] [blame]
Nanang Izzuddin57b88572009-04-01 12:05:34 +00001/* $Id$ */
2/*
Nanang Izzuddina62ffc92011-05-05 06:14:19 +00003 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
Nanang Izzuddin57b88572009-04-01 12:05:34 +00004 * 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>
Nanang Izzuddin9a71d8e2011-12-15 06:45:23 +000021#include <pjmedia-codec/g7221_sdp_match.h>
Nanang Izzuddin57b88572009-04-01 12:05:34 +000022#include <pjmedia/codec.h>
23#include <pjmedia/errno.h>
24#include <pjmedia/endpoint.h>
25#include <pjmedia/port.h>
26#include <pjmedia/silencedet.h>
27#include <pj/assert.h>
28#include <pj/log.h>
29#include <pj/math.h>
30#include <pj/pool.h>
31#include <pj/string.h>
32#include <pj/os.h>
33
34/*
35 * Only build this file if PJMEDIA_HAS_G7221_CODEC != 0
36 */
37#if defined(PJMEDIA_HAS_G7221_CODEC) && PJMEDIA_HAS_G7221_CODEC!=0
38
Nanang Izzuddin56e380a2009-04-15 14:45:41 +000039#include "../../../third_party/g7221/common/defs.h"
Nanang Izzuddin57b88572009-04-01 12:05:34 +000040
41#define THIS_FILE "g7221.c"
42
43/* Codec tag, it is the SDP encoding name and also MIME subtype name */
44#define CODEC_TAG "G7221"
45
46/* Sampling rates definition */
47#define WB_SAMPLE_RATE 16000
48#define UWB_SAMPLE_RATE 32000
49
50/* Maximum number of samples per frame. */
51#define MAX_SAMPLES_PER_FRAME (UWB_SAMPLE_RATE * 20 / 1000)
52
53/* Maximum number of codec params. */
54#define MAX_CODEC_MODES 8
55#define START_RSV_MODES_IDX 6
56
57
58/* Prototypes for G722.1 codec factory */
59static pj_status_t test_alloc( pjmedia_codec_factory *factory,
60 const pjmedia_codec_info *id );
61static pj_status_t default_attr( pjmedia_codec_factory *factory,
62 const pjmedia_codec_info *id,
63 pjmedia_codec_param *attr );
64static pj_status_t enum_codecs( pjmedia_codec_factory *factory,
65 unsigned *count,
66 pjmedia_codec_info codecs[]);
67static pj_status_t alloc_codec( pjmedia_codec_factory *factory,
68 const pjmedia_codec_info *id,
69 pjmedia_codec **p_codec);
70static pj_status_t dealloc_codec( pjmedia_codec_factory *factory,
71 pjmedia_codec *codec );
72
73/* Prototypes for G722.1 codec implementation. */
74static pj_status_t codec_init( pjmedia_codec *codec,
75 pj_pool_t *pool );
76static pj_status_t codec_open( pjmedia_codec *codec,
77 pjmedia_codec_param *attr );
78static pj_status_t codec_close( pjmedia_codec *codec );
79static pj_status_t codec_modify(pjmedia_codec *codec,
80 const pjmedia_codec_param *attr );
81static pj_status_t codec_parse( pjmedia_codec *codec,
82 void *pkt,
83 pj_size_t pkt_size,
84 const pj_timestamp *ts,
85 unsigned *frame_cnt,
86 pjmedia_frame frames[]);
87static pj_status_t codec_encode( pjmedia_codec *codec,
88 const struct pjmedia_frame *input,
89 unsigned output_buf_len,
90 struct pjmedia_frame *output);
91static pj_status_t codec_decode( pjmedia_codec *codec,
92 const struct pjmedia_frame *input,
93 unsigned output_buf_len,
94 struct pjmedia_frame *output);
95static pj_status_t codec_recover( pjmedia_codec *codec,
96 unsigned output_buf_len,
97 struct pjmedia_frame *output);
98
99/* Definition for G722.1 codec operations. */
100static pjmedia_codec_op codec_op =
101{
102 &codec_init,
103 &codec_open,
104 &codec_close,
105 &codec_modify,
106 &codec_parse,
107 &codec_encode,
108 &codec_decode,
109 &codec_recover
110};
111
112/* Definition for G722.1 codec factory operations. */
113static pjmedia_codec_factory_op codec_factory_op =
114{
115 &test_alloc,
116 &default_attr,
117 &enum_codecs,
118 &alloc_codec,
Benny Prijono35fc1eb2011-07-15 09:51:46 +0000119 &dealloc_codec,
120 &pjmedia_codec_g7221_deinit
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000121};
122
123
124/* Structure of G722.1 mode */
125typedef struct codec_mode
126{
127 pj_bool_t enabled; /* Is this mode enabled? */
128 pj_uint8_t pt; /* Payload type. */
129 unsigned sample_rate; /* Default sampling rate to be used.*/
130 unsigned bitrate; /* Bitrate. */
131 char bitrate_str[8]; /* Bitrate in string. */
132} codec_mode;
133
134
135/* G722.1 codec factory */
136static struct codec_factory {
137 pjmedia_codec_factory base; /**< Base class. */
138 pjmedia_endpt *endpt; /**< PJMEDIA endpoint instance. */
139 pj_pool_t *pool; /**< Codec factory pool. */
140 pj_mutex_t *mutex; /**< Codec factory mutex. */
141
Benny Prijono8496b932009-04-20 14:19:11 +0000142 int pcm_shift; /**< Level adjustment */
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000143 unsigned mode_count; /**< Number of G722.1 modes. */
144 codec_mode modes[MAX_CODEC_MODES]; /**< The G722.1 modes. */
145 unsigned mode_rsv_start;/**< Start index of G722.1 non-
146 standard modes, currently
147 there can only be up to two
148 non-standard modes enabled
149 at the same time. */
150} codec_factory;
151
152/* G722.1 codec private data. */
153typedef struct codec_private {
154 pj_pool_t *pool; /**< Pool for each instance. */
155 pj_bool_t plc_enabled; /**< PLC enabled? */
156 pj_bool_t vad_enabled; /**< VAD enabled? */
157 pjmedia_silence_det *vad; /**< PJMEDIA VAD instance. */
158 pj_timestamp last_tx; /**< Timestamp of last transmit.*/
159
160 /* ITU ref implementation seems to leave the codec engine states to be
161 * managed by the application, so here we go.
162 */
163
164 /* Common engine state */
165 pj_uint16_t samples_per_frame; /**< Samples per frame. */
166 pj_uint16_t bitrate; /**< Coded stream bitrate. */
167 pj_uint16_t frame_size; /**< Coded frame size. */
168 pj_uint16_t frame_size_bits; /**< Coded frame size in bits. */
169 pj_uint16_t number_of_regions; /**< Number of regions. */
Benny Prijono8496b932009-04-20 14:19:11 +0000170 int pcm_shift; /**< Adjustment for PCM in/out */
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000171
172 /* Encoder specific state */
Benny Prijono8496b932009-04-20 14:19:11 +0000173 Word16 *enc_frame; /**< 16bit to 14bit buffer */
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000174 Word16 *enc_old_frame;
175
176 /* Decoder specific state */
177 Word16 *dec_old_frame;
178 Rand_Obj dec_randobj;
179 Word16 dec_old_mag_shift;
180 Word16 *dec_old_mlt_coefs;
181} codec_private_t;
182
183/*
184 * Helper function for looking up mode based on payload type.
185 */
186static codec_mode* lookup_mode(unsigned pt)
187{
188 codec_mode* mode = NULL;
189 unsigned i;
190
191 for (i = 0; i < codec_factory.mode_count; ++i) {
192 mode = &codec_factory.modes[i];
193 if (mode->pt == pt)
194 break;
195 }
196
197 return mode;
198}
199
200/*
201 * Helper function to validate G722.1 mode. Valid modes are defined as:
202 * 1. sample rate must be 16kHz or 32kHz,
203 * 2. bitrate:
204 * - for sampling rate 16kHz: 16000 to 32000 bps, it must be a multiple
205 * of 400 (to keep RTP payload octed-aligned)
206 * - for sampling rate 32kHz: 24000 to 48000 bps, it must be a multiple
207 * of 400 (to keep RTP payload octed-aligned)
208 */
209static pj_bool_t validate_mode(unsigned sample_rate, unsigned bitrate)
210{
211 if (sample_rate == WB_SAMPLE_RATE) {
212 if (bitrate < 16000 || bitrate > 32000 ||
213 ((bitrate-16000) % 400 != 0))
214 {
215 return PJ_FALSE;
216 }
217 } else if (sample_rate == UWB_SAMPLE_RATE) {
218 if (bitrate < 24000 || bitrate > 48000 ||
219 ((bitrate-24000) % 400 != 0))
220 {
221 return PJ_FALSE;
222 }
223 } else {
224 return PJ_FALSE;
225 }
226
227 return PJ_TRUE;
228}
229
Benny Prijono3594ab32009-04-18 14:29:28 +0000230#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
231PJ_INLINE(void) swap_bytes(pj_uint16_t *buf, unsigned count)
232{
233 pj_uint16_t *end = buf + count;
234 while (buf != end) {
235 *buf = (pj_uint16_t)((*buf << 8) | (*buf >> 8));
236 ++buf;
237 }
238}
239#else
240#define swap_bytes(buf, count)
241#endif
242
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000243/*
244 * Initialize and register G722.1 codec factory to pjmedia endpoint.
245 */
246PJ_DEF(pj_status_t) pjmedia_codec_g7221_init( pjmedia_endpt *endpt )
247{
248 pjmedia_codec_mgr *codec_mgr;
249 codec_mode *mode;
Nanang Izzuddin9a71d8e2011-12-15 06:45:23 +0000250 pj_str_t codec_name;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000251 pj_status_t status;
252
253 if (codec_factory.pool != NULL) {
254 /* Already initialized. */
255 return PJ_SUCCESS;
256 }
257
258 /* Initialize codec modes, by default all standard bitrates are enabled */
Nanang Izzuddin27659812009-04-15 17:50:50 +0000259 codec_factory.mode_count = 0;
Benny Prijono8496b932009-04-20 14:19:11 +0000260 codec_factory.pcm_shift = PJMEDIA_G7221_DEFAULT_PCM_SHIFT;
Nanang Izzuddin27659812009-04-15 17:50:50 +0000261
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000262 mode = &codec_factory.modes[codec_factory.mode_count++];
263 mode->enabled = PJ_TRUE;
264 mode->pt = PJMEDIA_RTP_PT_G722_1_24;
265 mode->sample_rate = WB_SAMPLE_RATE;
266 mode->bitrate = 24000;
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_G722_1_32;
272 mode->sample_rate = WB_SAMPLE_RATE;
273 mode->bitrate = 32000;
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_24;
279 mode->sample_rate = UWB_SAMPLE_RATE;
280 mode->bitrate = 24000;
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_32;
286 mode->sample_rate = UWB_SAMPLE_RATE;
287 mode->bitrate = 32000;
288 pj_utoa(mode->bitrate, mode->bitrate_str);
289
290 mode = &codec_factory.modes[codec_factory.mode_count++];
291 mode->enabled = PJ_TRUE;
292 mode->pt = PJMEDIA_RTP_PT_G7221C_48;
293 mode->sample_rate = UWB_SAMPLE_RATE;
294 mode->bitrate = 48000;
295 pj_utoa(mode->bitrate, mode->bitrate_str);
296
297 /* Non-standard bitrates */
298
299 /* Bitrate 16kbps is non-standard but rather commonly used. */
300 mode = &codec_factory.modes[codec_factory.mode_count++];
301 mode->enabled = PJ_FALSE;
302 mode->pt = PJMEDIA_RTP_PT_G722_1_16;
303 mode->sample_rate = WB_SAMPLE_RATE;
304 mode->bitrate = 16000;
305 pj_utoa(mode->bitrate, mode->bitrate_str);
306
307 /* Reserved two modes for non-standard bitrates */
308 codec_factory.mode_rsv_start = codec_factory.mode_count;
309 mode = &codec_factory.modes[codec_factory.mode_count++];
310 mode->enabled = PJ_FALSE;
311 mode->pt = PJMEDIA_RTP_PT_G7221_RSV1;
312
313 mode = &codec_factory.modes[codec_factory.mode_count++];
314 mode->enabled = PJ_FALSE;
315 mode->pt = PJMEDIA_RTP_PT_G7221_RSV2;
316
317 pj_assert(codec_factory.mode_count <= MAX_CODEC_MODES);
318
319 /* Create G722.1 codec factory. */
320 codec_factory.base.op = &codec_factory_op;
321 codec_factory.base.factory_data = NULL;
322 codec_factory.endpt = endpt;
323
324 codec_factory.pool = pjmedia_endpt_create_pool(endpt, "G722.1 codec",
325 4000, 4000);
326 if (!codec_factory.pool)
327 return PJ_ENOMEM;
328
329 /* Create mutex. */
330 status = pj_mutex_create_simple(codec_factory.pool, "G722.1 codec",
331 &codec_factory.mutex);
332 if (status != PJ_SUCCESS)
333 goto on_error;
334
335 /* Get the codec manager. */
336 codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);
337 if (!codec_mgr) {
338 status = PJ_EINVALIDOP;
339 goto on_error;
340 }
341
Nanang Izzuddin9a71d8e2011-12-15 06:45:23 +0000342 /* Register format match callback. */
343 pj_cstr(&codec_name, CODEC_TAG);
344 status = pjmedia_sdp_neg_register_fmt_match_cb(
345 &codec_name,
346 &pjmedia_codec_g7221_match_sdp);
347 if (status != PJ_SUCCESS)
348 goto on_error;
349
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000350 /* Register codec factory to endpoint. */
351 status = pjmedia_codec_mgr_register_factory(codec_mgr,
352 &codec_factory.base);
353 if (status != PJ_SUCCESS)
354 goto on_error;
355
356 /* Done. */
357 return PJ_SUCCESS;
358
359on_error:
360 if (codec_factory.mutex) {
361 pj_mutex_destroy(codec_factory.mutex);
362 codec_factory.mutex = NULL;
363 }
364
365 pj_pool_release(codec_factory.pool);
366 codec_factory.pool = NULL;
367 return status;
368}
369
370
371/**
372 * Enable and disable G722.1 modes, including non-standard modes.
373 */
374PJ_DEF(pj_status_t) pjmedia_codec_g7221_set_mode(unsigned sample_rate,
375 unsigned bitrate,
376 pj_bool_t enabled)
377{
378 unsigned i;
379
380 /* Validate mode */
381 if (!validate_mode(sample_rate, bitrate))
382 return PJMEDIA_CODEC_EINMODE;
383
384 /* Look up in factory modes table */
385 for (i = 0; i < codec_factory.mode_count; ++i) {
386 if (codec_factory.modes[i].sample_rate == sample_rate &&
387 codec_factory.modes[i].bitrate == bitrate)
388 {
389 codec_factory.modes[i].enabled = enabled;
390 return PJ_SUCCESS;
391 }
392 }
393
394 /* Mode not found in modes table, this may be a request to enable
395 * a non-standard G722.1 mode.
396 */
397
398 /* Non-standard mode need to be initialized first before user
399 * can disable it.
400 */
401 if (!enabled)
402 return PJ_ENOTFOUND;
403
404 /* Initialize a non-standard mode, look for available space. */
405 for (i = codec_factory.mode_rsv_start;
406 i < codec_factory.mode_count; ++i)
407 {
408 if (!codec_factory.modes[i].enabled)
409 {
410 codec_mode *mode = &codec_factory.modes[i];
411 mode->enabled = PJ_TRUE;
412 mode->sample_rate = sample_rate;
413 mode->bitrate = bitrate;
414 pj_utoa(mode->bitrate, mode->bitrate_str);
415
416 return PJ_SUCCESS;
417 }
418 }
419
420 /* No space for non-standard mode. */
421 return PJ_ETOOMANY;
422}
423
424
425/*
Benny Prijono8496b932009-04-20 14:19:11 +0000426 * Set level adjustment.
427 */
428PJ_DEF(pj_status_t) pjmedia_codec_g7221_set_pcm_shift(int val)
429{
430 codec_factory.pcm_shift = val;
431 return PJ_SUCCESS;
432}
433
434/*
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000435 * Unregister G722.1 codec factory from pjmedia endpoint.
436 */
437PJ_DEF(pj_status_t) pjmedia_codec_g7221_deinit(void)
438{
439 pjmedia_codec_mgr *codec_mgr;
440 pj_status_t status;
441
442 if (codec_factory.pool == NULL) {
443 /* Already deinitialized */
444 return PJ_SUCCESS;
445 }
446
447 pj_mutex_lock(codec_factory.mutex);
448
449 /* Get the codec manager. */
450 codec_mgr = pjmedia_endpt_get_codec_mgr(codec_factory.endpt);
451 if (!codec_mgr) {
452 pj_pool_release(codec_factory.pool);
453 codec_factory.pool = NULL;
454 return PJ_EINVALIDOP;
455 }
456
457 /* Unregister G722.1 codec factory. */
458 status = pjmedia_codec_mgr_unregister_factory(codec_mgr,
459 &codec_factory.base);
460
461 /* Destroy mutex. */
462 pj_mutex_destroy(codec_factory.mutex);
463
464 /* Destroy pool. */
465 pj_pool_release(codec_factory.pool);
466 codec_factory.pool = NULL;
467
468 return status;
469}
470
471/*
472 * Check if factory can allocate the specified codec.
473 */
474static pj_status_t test_alloc( pjmedia_codec_factory *factory,
475 const pjmedia_codec_info *info )
476{
477 PJ_UNUSED_ARG(factory);
478
479 /* Type MUST be audio. */
480 if (info->type != PJMEDIA_TYPE_AUDIO)
481 return PJMEDIA_CODEC_EUNSUP;
482
483 /* Check encoding name. */
484 if (pj_stricmp2(&info->encoding_name, CODEC_TAG) != 0)
485 return PJMEDIA_CODEC_EUNSUP;
486
487 /* Check clock-rate */
488 if (info->clock_rate != WB_SAMPLE_RATE &&
489 info->clock_rate != UWB_SAMPLE_RATE)
490 {
491 return PJMEDIA_CODEC_EUNSUP;
492 }
493
494 return PJ_SUCCESS;
495}
496
497/*
498 * Generate default attribute.
499 */
500static pj_status_t default_attr ( pjmedia_codec_factory *factory,
501 const pjmedia_codec_info *id,
502 pjmedia_codec_param *attr )
503{
504 codec_mode *mode;
505
506 PJ_ASSERT_RETURN(factory==&codec_factory.base, PJ_EINVAL);
507
508 pj_bzero(attr, sizeof(pjmedia_codec_param));
509
510 mode = lookup_mode(id->pt);
511 if (mode == NULL || !mode->enabled)
512 return PJMEDIA_CODEC_EUNSUP;
513
514 attr->info.pt = (pj_uint8_t)id->pt;
515 attr->info.channel_cnt = 1;
516 attr->info.clock_rate = mode->sample_rate;
517 attr->info.max_bps = mode->bitrate;
518 attr->info.avg_bps = mode->bitrate;
519 attr->info.pcm_bits_per_sample = 16;
520 attr->info.frm_ptime = 20;
521
522 /* Default flags. */
523 attr->setting.plc = 1;
524 attr->setting.vad = 0;
525 attr->setting.frm_per_pkt = 1;
526
527 /* Default FMTP setting */
528 attr->setting.dec_fmtp.cnt = 1;
529 attr->setting.dec_fmtp.param[0].name = pj_str("bitrate");
530 attr->setting.dec_fmtp.param[0].val = pj_str(mode->bitrate_str);
531
532 return PJ_SUCCESS;
533}
534
535/*
536 * Enum codecs supported by this factory.
537 */
538static pj_status_t enum_codecs( pjmedia_codec_factory *factory,
539 unsigned *count,
540 pjmedia_codec_info codecs[])
541{
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000542 unsigned i, max_cnt;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000543
544 PJ_ASSERT_RETURN(factory==&codec_factory.base, PJ_EINVAL);
545 PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);
546
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000547 max_cnt = *count;
548 *count = 0;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000549
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000550 for (i=0; (i < codec_factory.mode_count) && (*count < max_cnt); ++i)
551 {
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000552 if (!codec_factory.modes[i].enabled)
553 continue;
554
Nanang Izzuddinf484a1d2009-04-02 10:41:22 +0000555 pj_bzero(&codecs[*count], sizeof(pjmedia_codec_info));
556 codecs[*count].encoding_name = pj_str((char*)CODEC_TAG);
557 codecs[*count].pt = codec_factory.modes[i].pt;
558 codecs[*count].type = PJMEDIA_TYPE_AUDIO;
559 codecs[*count].clock_rate = codec_factory.modes[i].sample_rate;
560 codecs[*count].channel_cnt = 1;
561
562 ++ *count;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000563 }
564
565 return PJ_SUCCESS;
566}
567
568/*
569 * Allocate a new codec instance.
570 */
571static pj_status_t alloc_codec( pjmedia_codec_factory *factory,
572 const pjmedia_codec_info *id,
573 pjmedia_codec **p_codec)
574{
575 codec_private_t *codec_data;
576 pjmedia_codec *codec;
577 pj_pool_t *pool;
578 pj_status_t status;
579
580 PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);
581 PJ_ASSERT_RETURN(factory == &codec_factory.base, PJ_EINVAL);
582
583 pj_mutex_lock(codec_factory.mutex);
584
585 /* Create pool for codec instance */
586 pool = pjmedia_endpt_create_pool(codec_factory.endpt, "G7221", 512, 512);
587 codec = PJ_POOL_ZALLOC_T(pool, pjmedia_codec);
588 codec->op = &codec_op;
589 codec->factory = factory;
590 codec->codec_data = PJ_POOL_ZALLOC_T(pool, codec_private_t);
591 codec_data = (codec_private_t*) codec->codec_data;
592 codec_data->pool = pool;
593
594 /* Create silence detector */
595 status = pjmedia_silence_det_create(pool, id->clock_rate,
596 id->clock_rate * 20 / 1000,
597 &codec_data->vad);
598 if (status != PJ_SUCCESS) {
599 pj_mutex_unlock(codec_factory.mutex);
600 return status;
601 }
602
603 pj_mutex_unlock(codec_factory.mutex);
604
605 *p_codec = codec;
606 return PJ_SUCCESS;
607}
608
609/*
610 * Free codec.
611 */
612static pj_status_t dealloc_codec( pjmedia_codec_factory *factory,
613 pjmedia_codec *codec )
614{
615 codec_private_t *codec_data;
616 pj_pool_t *pool;
617
618 PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);
619 PJ_ASSERT_RETURN(factory == &codec_factory.base, PJ_EINVAL);
620
621 /* Close codec, if it's not closed. */
622 codec_data = (codec_private_t*) codec->codec_data;
623 pool = codec_data->pool;
624 codec_close(codec);
625
626 /* Release codec pool */
627 pj_pool_release(pool);
628
629 return PJ_SUCCESS;
630}
631
632/*
633 * Init codec.
634 */
635static pj_status_t codec_init( pjmedia_codec *codec,
636 pj_pool_t *pool )
637{
638 PJ_UNUSED_ARG(codec);
639 PJ_UNUSED_ARG(pool);
640 return PJ_SUCCESS;
641}
642
643/*
644 * Open codec.
645 */
646static pj_status_t codec_open( pjmedia_codec *codec,
647 pjmedia_codec_param *attr )
648{
649 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
650 pj_pool_t *pool;
651 unsigned tmp;
652
653 /* Validation mode first! */
654 if (!validate_mode(attr->info.clock_rate, attr->info.avg_bps))
655 return PJMEDIA_CODEC_EINMODE;
656
657 pool = codec_data->pool;
658
659 /* Initialize common state */
660 codec_data->vad_enabled = (attr->setting.vad != 0);
661 codec_data->plc_enabled = (attr->setting.plc != 0);
662
663 codec_data->bitrate = (pj_uint16_t)attr->info.avg_bps;
664 codec_data->frame_size_bits = (pj_uint16_t)(attr->info.avg_bps*20/1000);
665 codec_data->frame_size = (pj_uint16_t)(codec_data->frame_size_bits>>3);
666 codec_data->samples_per_frame = (pj_uint16_t)
667 (attr->info.clock_rate*20/1000);
668 codec_data->number_of_regions = (pj_uint16_t)
669 (attr->info.clock_rate <= WB_SAMPLE_RATE?
670 NUMBER_OF_REGIONS:MAX_NUMBER_OF_REGIONS);
Benny Prijono8496b932009-04-20 14:19:11 +0000671 codec_data->pcm_shift = codec_factory.pcm_shift;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000672
673 /* Initialize encoder state */
674 tmp = codec_data->samples_per_frame << 1;
675 codec_data->enc_old_frame = (Word16*)pj_pool_zalloc(pool, tmp);
Benny Prijono8496b932009-04-20 14:19:11 +0000676 codec_data->enc_frame = (Word16*)pj_pool_alloc(pool, tmp);
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000677
678 /* Initialize decoder state */
679 tmp = codec_data->samples_per_frame;
680 codec_data->dec_old_frame = (Word16*)pj_pool_zalloc(pool, tmp);
681
682 tmp = codec_data->samples_per_frame << 1;
683 codec_data->dec_old_mlt_coefs = (Word16*)pj_pool_zalloc(pool, tmp);
684
685 codec_data->dec_randobj.seed0 = 1;
686 codec_data->dec_randobj.seed1 = 1;
687 codec_data->dec_randobj.seed2 = 1;
688 codec_data->dec_randobj.seed3 = 1;
689
690 return PJ_SUCCESS;
691}
692
693/*
694 * Close codec.
695 */
696static pj_status_t codec_close( pjmedia_codec *codec )
697{
698 PJ_UNUSED_ARG(codec);
699
700 return PJ_SUCCESS;
701}
702
703
704/*
705 * Modify codec settings.
706 */
707static pj_status_t codec_modify( pjmedia_codec *codec,
708 const pjmedia_codec_param *attr )
709{
710 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
711
712 codec_data->vad_enabled = (attr->setting.vad != 0);
713 codec_data->plc_enabled = (attr->setting.plc != 0);
714
715 return PJ_SUCCESS;
716}
717
718/*
719 * Get frames in the packet.
720 */
721static pj_status_t codec_parse( pjmedia_codec *codec,
722 void *pkt,
723 pj_size_t pkt_size,
724 const pj_timestamp *ts,
725 unsigned *frame_cnt,
726 pjmedia_frame frames[])
727{
728 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
729 unsigned count = 0;
730
731 PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);
732
733 /* Parse based on fixed frame size. */
734 while (pkt_size >= codec_data->frame_size && count < *frame_cnt) {
735 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;
736 frames[count].buf = pkt;
737 frames[count].size = codec_data->frame_size;
738 frames[count].timestamp.u64 = ts->u64 +
739 count * codec_data->samples_per_frame;
740
741 pkt = (pj_uint8_t*)pkt + codec_data->frame_size;
742 pkt_size -= codec_data->frame_size;
743
744 ++count;
745 }
746
747 pj_assert(pkt_size == 0);
748 *frame_cnt = count;
749
750 return PJ_SUCCESS;
751}
752
753/*
754 * Encode frames.
755 */
756static pj_status_t codec_encode( pjmedia_codec *codec,
757 const struct pjmedia_frame *input,
758 unsigned output_buf_len,
759 struct pjmedia_frame *output)
760{
761 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
Benny Prijono8496b932009-04-20 14:19:11 +0000762 const Word16 *pcm_input;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000763 Word16 mlt_coefs[MAX_SAMPLES_PER_FRAME];
764 Word16 mag_shift;
765
766 /* Check frame in & out size */
767 PJ_ASSERT_RETURN((pj_uint16_t)input->size ==
768 (codec_data->samples_per_frame<<1),
769 PJMEDIA_CODEC_EPCMTOOSHORT);
770 PJ_ASSERT_RETURN(output_buf_len >= codec_data->frame_size,
771 PJMEDIA_CODEC_EFRMTOOSHORT);
772
773 /* Apply silence detection if VAD is enabled */
774 if (codec_data->vad_enabled) {
775 pj_bool_t is_silence;
776 pj_int32_t silence_duration;
777
778 pj_assert(codec_data->vad);
779
780 silence_duration = pj_timestamp_diff32(&codec_data->last_tx,
781 &input->timestamp);
782
783 is_silence = pjmedia_silence_det_detect(codec_data->vad,
784 (const pj_int16_t*) input->buf,
785 (input->size >> 1),
786 NULL);
787 if (is_silence &&
Nanang Izzuddin4ff93f42009-06-13 15:28:37 +0000788 (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||
789 silence_duration < (PJMEDIA_CODEC_MAX_SILENCE_PERIOD *
790 (int)codec_data->samples_per_frame / 20)))
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000791 {
792 output->type = PJMEDIA_FRAME_TYPE_NONE;
793 output->buf = NULL;
794 output->size = 0;
795 output->timestamp = input->timestamp;
796 return PJ_SUCCESS;
797 } else {
798 codec_data->last_tx = input->timestamp;
799 }
800 }
801
Benny Prijono8496b932009-04-20 14:19:11 +0000802 /* Encoder adjust the input signal level */
803 if (codec_data->pcm_shift) {
804 unsigned i;
805 pcm_input = (const Word16*)input->buf;
806 for (i=0; i<codec_data->samples_per_frame; ++i) {
807 codec_data->enc_frame[i] =
808 (pj_int16_t)(pcm_input[i] >> codec_data->pcm_shift);
809 }
810 pcm_input = codec_data->enc_frame;
811 } else {
812 pcm_input = (const Word16*)input->buf;
813 }
814
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000815 /* Convert input samples to rmlt coefs */
Benny Prijono8496b932009-04-20 14:19:11 +0000816 mag_shift = samples_to_rmlt_coefs(pcm_input,
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000817 codec_data->enc_old_frame,
818 mlt_coefs,
819 codec_data->samples_per_frame);
820
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000821 /* Encode the mlt coefs. Note that encoder output stream is 16 bit array,
822 * so we need to take care about endianness.
823 */
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000824 encoder(codec_data->frame_size_bits,
825 codec_data->number_of_regions,
826 mlt_coefs,
827 mag_shift,
828 output->buf);
829
Benny Prijono3594ab32009-04-18 14:29:28 +0000830 /* Encoder output are in native host byte order, while ITU says
831 * it must be in network byte order (MSB first).
832 */
833 swap_bytes((pj_uint16_t*)output->buf, codec_data->frame_size/2);
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000834
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000835 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
836 output->size = codec_data->frame_size;
Nanang Izzuddin5fe03142009-06-02 18:01:49 +0000837 output->timestamp = input->timestamp;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000838
839 return PJ_SUCCESS;
840}
841
842/*
843 * Decode frame.
844 */
845static pj_status_t codec_decode( pjmedia_codec *codec,
846 const struct pjmedia_frame *input,
847 unsigned output_buf_len,
848 struct pjmedia_frame *output)
849{
850 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
851 Word16 mlt_coefs[MAX_SAMPLES_PER_FRAME];
852 Word16 mag_shift;
853 Bit_Obj bitobj;
854 Word16 frame_error_flag = 0;
855
856 /* Check frame out length size */
857 PJ_ASSERT_RETURN(output_buf_len >=
858 (unsigned)(codec_data->samples_per_frame<<1),
859 PJMEDIA_CODEC_EPCMTOOSHORT);
860
861 /* If input is NULL, perform PLC by settting frame_error_flag to 1 */
862 if (input) {
863 /* Check frame in length size */
864 PJ_ASSERT_RETURN((pj_uint16_t)input->size == codec_data->frame_size,
865 PJMEDIA_CODEC_EFRMINLEN);
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000866
Benny Prijono3594ab32009-04-18 14:29:28 +0000867 /* Decoder requires input of 16-bits array in native host byte
868 * order, while the frame received from the network are in
869 * network byte order (MSB first).
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000870 */
Benny Prijono3594ab32009-04-18 14:29:28 +0000871 swap_bytes((pj_uint16_t*)input->buf, codec_data->frame_size/2);
Nanang Izzuddin134989a2009-04-06 11:45:25 +0000872
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000873 bitobj.code_word_ptr = (Word16*)input->buf;
874 bitobj.current_word = *bitobj.code_word_ptr;
875 bitobj.code_bit_count = 0;
876 bitobj.number_of_bits_left = codec_data->frame_size_bits;
Nanang Izzuddin5fe03142009-06-02 18:01:49 +0000877
878 output->timestamp = input->timestamp;
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000879 } else {
880 pj_bzero(&bitobj, sizeof(bitobj));
881 frame_error_flag = 1;
882 }
883
884 /* Process the input frame to get mlt coefs */
885 decoder(&bitobj,
886 &codec_data->dec_randobj,
887 codec_data->number_of_regions,
888 mlt_coefs,
889 &mag_shift,
890 &codec_data->dec_old_mag_shift,
891 codec_data->dec_old_mlt_coefs,
892 frame_error_flag);
893
894 /* Convert the mlt_coefs to PCM samples */
895 rmlt_coefs_to_samples(mlt_coefs,
896 codec_data->dec_old_frame,
897 (Word16*)output->buf,
898 codec_data->samples_per_frame,
899 mag_shift);
900
Benny Prijono8496b932009-04-20 14:19:11 +0000901 /* Decoder adjust PCM signal */
902 if (codec_data->pcm_shift) {
903 unsigned i;
904 pj_int16_t *buf = (Word16*)output->buf;
905
906 for (i=0; i<codec_data->samples_per_frame; ++i) {
907 buf[i] <<= codec_data->pcm_shift;
908 }
909 }
910
Nanang Izzuddin57b88572009-04-01 12:05:34 +0000911 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
912 output->size = codec_data->samples_per_frame << 1;
913
914 return PJ_SUCCESS;
915}
916
917/*
918 * Recover lost frame.
919 */
920static pj_status_t codec_recover( pjmedia_codec *codec,
921 unsigned output_buf_len,
922 struct pjmedia_frame *output)
923{
924 codec_private_t *codec_data = (codec_private_t*) codec->codec_data;
925
926 /* Use native PLC when PLC is enabled. */
927 if (codec_data->plc_enabled)
928 return codec_decode(codec, NULL, output_buf_len, output);
929
930 /* Otherwise just return zero-fill frame. */
931 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
932 output->size = codec_data->samples_per_frame << 1;
933
934 pjmedia_zero_samples((pj_int16_t*)output->buf,
935 codec_data->samples_per_frame);
936
937 return PJ_SUCCESS;
938}
939
940#endif /* PJMEDIA_HAS_G7221_CODEC */