blob: 50926173b5ceb11307a265c6337ca6a590bdad7b [file] [log] [blame]
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001/* $Id$ */
2/*
3 * Copyright (C)2003-2008 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include <pjmedia-codec/ipp_codecs.h>
20#include <pjmedia/codec.h>
21#include <pjmedia/errno.h>
22#include <pjmedia/endpoint.h>
23#include <pjmedia/plc.h>
24#include <pjmedia/port.h>
25#include <pjmedia/silencedet.h>
26#include <pj/assert.h>
27#include <pj/log.h>
28#include <pj/pool.h>
29#include <pj/string.h>
30#include <pj/os.h>
31
Nanang Izzuddin23a00b72008-08-25 13:58:25 +000032
Nanang Izzuddin493a8db2008-08-15 13:17:39 +000033/*
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +000034 * Only build this file if PJMEDIA_HAS_INTEL_IPP != 0
Nanang Izzuddin493a8db2008-08-15 13:17:39 +000035 */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +000036#if defined(PJMEDIA_HAS_INTEL_IPP) && PJMEDIA_HAS_INTEL_IPP != 0
Nanang Izzuddin493a8db2008-08-15 13:17:39 +000037
38#include <usc.h>
39
40#define THIS_FILE "ipp_codecs.c"
41
42/* Prototypes for IPP codecs factory */
43static pj_status_t ipp_test_alloc( pjmedia_codec_factory *factory,
44 const pjmedia_codec_info *id );
45static pj_status_t ipp_default_attr( pjmedia_codec_factory *factory,
46 const pjmedia_codec_info *id,
47 pjmedia_codec_param *attr );
48static pj_status_t ipp_enum_codecs( pjmedia_codec_factory *factory,
49 unsigned *count,
50 pjmedia_codec_info codecs[]);
51static pj_status_t ipp_alloc_codec( pjmedia_codec_factory *factory,
52 const pjmedia_codec_info *id,
53 pjmedia_codec **p_codec);
54static pj_status_t ipp_dealloc_codec( pjmedia_codec_factory *factory,
55 pjmedia_codec *codec );
56
57/* Prototypes for IPP codecs implementation. */
58static pj_status_t ipp_codec_init( pjmedia_codec *codec,
59 pj_pool_t *pool );
60static pj_status_t ipp_codec_open( pjmedia_codec *codec,
61 pjmedia_codec_param *attr );
62static pj_status_t ipp_codec_close( pjmedia_codec *codec );
63static pj_status_t ipp_codec_modify(pjmedia_codec *codec,
64 const pjmedia_codec_param *attr );
65static pj_status_t ipp_codec_parse( pjmedia_codec *codec,
66 void *pkt,
67 pj_size_t pkt_size,
68 const pj_timestamp *ts,
69 unsigned *frame_cnt,
70 pjmedia_frame frames[]);
71static pj_status_t ipp_codec_encode( pjmedia_codec *codec,
72 const struct pjmedia_frame *input,
73 unsigned output_buf_len,
74 struct pjmedia_frame *output);
75static pj_status_t ipp_codec_decode( pjmedia_codec *codec,
76 const struct pjmedia_frame *input,
77 unsigned output_buf_len,
78 struct pjmedia_frame *output);
79static pj_status_t ipp_codec_recover(pjmedia_codec *codec,
80 unsigned output_buf_len,
81 struct pjmedia_frame *output);
82
83/* Definition for IPP codecs operations. */
84static pjmedia_codec_op ipp_op =
85{
86 &ipp_codec_init,
87 &ipp_codec_open,
88 &ipp_codec_close,
89 &ipp_codec_modify,
90 &ipp_codec_parse,
91 &ipp_codec_encode,
92 &ipp_codec_decode,
93 &ipp_codec_recover
94};
95
96/* Definition for IPP codecs factory operations. */
97static pjmedia_codec_factory_op ipp_factory_op =
98{
99 &ipp_test_alloc,
100 &ipp_default_attr,
101 &ipp_enum_codecs,
102 &ipp_alloc_codec,
103 &ipp_dealloc_codec
104};
105
106/* IPP codecs factory */
107static struct ipp_factory {
108 pjmedia_codec_factory base;
109 pjmedia_endpt *endpt;
110 pj_pool_t *pool;
111 pj_mutex_t *mutex;
112} ipp_factory;
113
114/* IPP codecs private data. */
115typedef struct ipp_private {
116 int codec_idx; /**< Codec index. */
117 pj_pool_t *pool; /**< Pool for each instance. */
118
119 USC_Handle enc; /**< Encoder state. */
120 USC_Handle dec; /**< Decoder state. */
121 USC_CodecInfo *info; /**< Native codec info. */
122 pj_uint16_t frame_size; /**< Bitstream frame size. */
123
124 pj_bool_t plc_enabled;
125 pjmedia_plc *plc;
126
127 pj_bool_t vad_enabled;
128 pjmedia_silence_det *vad;
129 pj_timestamp last_tx;
130} ipp_private_t;
131
132
133/* USC codec implementations. */
134extern USC_Fxns USC_G729AFP_Fxns;
135extern USC_Fxns USC_G723_Fxns;
136extern USC_Fxns USC_G726_Fxns;
137extern USC_Fxns USC_G728_Fxns;
138extern USC_Fxns USC_G722_Fxns;
139extern USC_Fxns USC_GSMAMR_Fxns;
140extern USC_Fxns USC_AMRWB_Fxns;
141extern USC_Fxns USC_AMRWBE_Fxns;
142
143/* CUSTOM CALLBACKS */
144
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000145/* This callback is useful for translating RTP frame into USC frame, e.g:
146 * reassigning frame attributes, reorder bitstream. Default behaviour of
147 * the translation is just setting the USC frame buffer & its size as
148 * specified in RTP frame, setting USC frame frametype to 0, setting bitrate
149 * of USC frame to bitrate info of codec_data. Implement this callback when
150 * the default behaviour is unapplicable.
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000151 */
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000152typedef void (*predecode_cb)(ipp_private_t *codec_data,
153 const pjmedia_frame *rtp_frame,
154 USC_Bitstream *usc_frame);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000155
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000156/* Parse frames from a packet. Default behaviour of frame parsing is
157 * just separating frames based on calculating frame length derived
158 * from bitrate. Implement this callback when the default behaviour is
159 * unapplicable.
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000160 */
161typedef pj_status_t (*parse_cb)(ipp_private_t *codec_data, void *pkt,
162 pj_size_t pkt_size, const pj_timestamp *ts,
163 unsigned *frame_cnt, pjmedia_frame frames[]);
164
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000165/* Pack frames into a packet. Default behaviour of packing frames is
166 * just stacking the frames with octet aligned without adding any
167 * payload header. Implement this callback when the default behaviour is
168 * unapplicable.
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000169 */
170typedef pj_status_t (*pack_cb)(ipp_private_t *codec_data, void *pkt,
171 pj_size_t *pkt_size, pj_size_t max_pkt_size);
172
173
174
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000175/* Custom callback implementations. */
176static void predecode_g723( ipp_private_t *codec_data,
177 const pjmedia_frame *rtp_frame,
178 USC_Bitstream *usc_frame);
179static pj_status_t parse_g723( ipp_private_t *codec_data, void *pkt,
180 pj_size_t pkt_size, const pj_timestamp *ts,
181 unsigned *frame_cnt, pjmedia_frame frames[]);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000182
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000183static void predecode_g729( ipp_private_t *codec_data,
184 const pjmedia_frame *rtp_frame,
185 USC_Bitstream *usc_frame);
186
187static void predecode_amr( ipp_private_t *codec_data,
188 const pjmedia_frame *rtp_frame,
189 USC_Bitstream *usc_frame);
190static pj_status_t parse_amr( ipp_private_t *codec_data, void *pkt,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000191 pj_size_t pkt_size, const pj_timestamp *ts,
192 unsigned *frame_cnt, pjmedia_frame frames[]);
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000193static pj_status_t pack_amr( ipp_private_t *codec_data, void *pkt,
194 pj_size_t *pkt_size, pj_size_t max_pkt_size);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000195
196
197/* IPP codec implementation descriptions. */
198static struct ipp_codec {
199 int enabled; /* Is this codec enabled? */
200 const char *name; /* Codec name. */
201 pj_uint8_t pt; /* Payload type. */
202 USC_Fxns *fxns; /* USC callback functions. */
203 unsigned clock_rate; /* Codec's clock rate. */
204 unsigned channel_count; /* Codec's channel count. */
205 unsigned samples_per_frame; /* Codec's samples count. */
206
207 unsigned def_bitrate; /* Default bitrate of this codec. */
208 unsigned max_bitrate; /* Maximum bitrate of this codec. */
209 pj_uint8_t frm_per_pkt; /* Default num of frames per packet.*/
210 int has_native_vad; /* Codec has internal VAD? */
211 int has_native_plc; /* Codec has internal PLC? */
212
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000213 predecode_cb predecode; /* Callback to translate RTP frame
Nanang Izzuddin23a00b72008-08-25 13:58:25 +0000214 into USC frame. */
215 parse_cb parse; /* Callback to parse bitstream. */
216 pack_cb pack; /* Callback to pack bitstream. */
217
218 pjmedia_codec_fmtp dec_fmtp; /* Decoder's fmtp params. */
219}
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000220
221ipp_codec[] =
222{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000223# if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000224 {1, "AMR", PJMEDIA_RTP_PT_AMR, &USC_GSMAMR_Fxns, 8000, 1, 160,
225 5900, 12200, 4, 1, 1,
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000226 &predecode_amr, &parse_amr, &pack_amr
227 },
228# endif
229
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000230# if PJMEDIA_HAS_INTEL_IPP_CODEC_AMRWB
231 {1, "AMR-WB", PJMEDIA_RTP_PT_AMRWB, &USC_AMRWB_Fxns, 16000, 1, 320,
232 15850, 23850, 1, 1, 1,
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000233 &predecode_amr, &parse_amr, &pack_amr
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000234 },
235# endif
236
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000237# if PJMEDIA_HAS_INTEL_IPP_CODEC_G729
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000238 {1, "G729", PJMEDIA_RTP_PT_G729, &USC_G729AFP_Fxns, 8000, 1, 80,
Nanang Izzuddin23a00b72008-08-25 13:58:25 +0000239 8000, 11800, 2, 1, 1,
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000240 &predecode_g729, NULL, NULL
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000241 },
242# endif
243
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000244# if PJMEDIA_HAS_INTEL_IPP_CODEC_G723_1
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000245 /* This is actually G.723.1 */
246 {1, "G723", PJMEDIA_RTP_PT_G723, &USC_G723_Fxns, 8000, 1, 240,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000247 6300, 6300, 1, 1, 1,
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000248 &predecode_g723, &parse_g723, NULL
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000249 },
250# endif
251
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000252# if PJMEDIA_HAS_INTEL_IPP_CODEC_G726
Nanang Izzuddinf216f822008-08-15 18:35:50 +0000253 {0, "G726-16", PJMEDIA_RTP_PT_G726_16, &USC_G726_Fxns, 8000, 1, 80,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000254 16000, 16000, 2, 0, 0,
255 NULL, NULL, NULL
256 },
Nanang Izzuddinf216f822008-08-15 18:35:50 +0000257 {0, "G726-24", PJMEDIA_RTP_PT_G726_24, &USC_G726_Fxns, 8000, 1, 80,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000258 24000, 24000, 2, 0, 0,
259 NULL, NULL, NULL
260 },
261 {1, "G726-32", PJMEDIA_RTP_PT_G726_32, &USC_G726_Fxns, 8000, 1, 80,
262 32000, 32000, 2, 0, 0,
263 NULL, NULL, NULL
264 },
Nanang Izzuddinf216f822008-08-15 18:35:50 +0000265 {0, "G726-40", PJMEDIA_RTP_PT_G726_40, &USC_G726_Fxns, 8000, 1, 80,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000266 40000, 40000, 2, 0, 0,
267 NULL, NULL, NULL
268 },
269# endif
270
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000271# if PJMEDIA_HAS_INTEL_IPP_CODEC_G728
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000272 {1, "G728", PJMEDIA_RTP_PT_G728, &USC_G728_Fxns, 8000, 1, 80,
273 16000, 16000, 2, 0, 1,
274 NULL, NULL, NULL
275 },
276# endif
277
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000278# if PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1
Nanang Izzuddin23a00b72008-08-25 13:58:25 +0000279 {0, "G7221", PJMEDIA_RTP_PT_G722_1_16, &USC_G722_Fxns, 16000, 1, 320,
280 16000, 16000, 1, 0, 1,
281 NULL, NULL, NULL,
282 {1, {{{"bitrate", 7}, {"16000", 5}}} }
283 },
284 {1, "G7221", PJMEDIA_RTP_PT_G722_1_24, &USC_G722_Fxns, 16000, 1, 320,
285 24000, 24000, 1, 0, 1,
286 NULL, NULL, NULL,
287 {1, {{{"bitrate", 7}, {"24000", 5}}} }
288 },
289 {1, "G7221", PJMEDIA_RTP_PT_G722_1_32, &USC_G722_Fxns, 16000, 1, 320,
290 32000, 32000, 1, 0, 1,
291 NULL, NULL, NULL,
292 {1, {{{"bitrate", 7}, {"32000", 5}}} }
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000293 },
294# endif
295};
296
297
298static int amr_get_mode(unsigned bitrate);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000299
300/*
301 * Initialize and register IPP codec factory to pjmedia endpoint.
302 */
303PJ_DEF(pj_status_t) pjmedia_codec_ipp_init( pjmedia_endpt *endpt )
304{
305 pjmedia_codec_mgr *codec_mgr;
306 pj_status_t status;
307
308 if (ipp_factory.pool != NULL) {
309 /* Already initialized. */
310 return PJ_SUCCESS;
311 }
312
313 /* Create IPP codec factory. */
314 ipp_factory.base.op = &ipp_factory_op;
315 ipp_factory.base.factory_data = NULL;
316 ipp_factory.endpt = endpt;
317
318 ipp_factory.pool = pjmedia_endpt_create_pool(endpt, "IPP codecs", 4000, 4000);
319 if (!ipp_factory.pool)
320 return PJ_ENOMEM;
321
322 /* Create mutex. */
323 status = pj_mutex_create_simple(ipp_factory.pool, "IPP codecs",
324 &ipp_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 &ipp_factory.base);
338 if (status != PJ_SUCCESS)
339 goto on_error;
340
341 /* Done. */
342 return PJ_SUCCESS;
343
344on_error:
345 pj_pool_release(ipp_factory.pool);
346 ipp_factory.pool = NULL;
347 return status;
348}
349
350/*
351 * Unregister IPP codecs factory from pjmedia endpoint.
352 */
353PJ_DEF(pj_status_t) pjmedia_codec_ipp_deinit(void)
354{
355 pjmedia_codec_mgr *codec_mgr;
356 pj_status_t status;
357
358 if (ipp_factory.pool == NULL) {
359 /* Already deinitialized */
360 return PJ_SUCCESS;
361 }
362
363 pj_mutex_lock(ipp_factory.mutex);
364
365 /* Get the codec manager. */
366 codec_mgr = pjmedia_endpt_get_codec_mgr(ipp_factory.endpt);
367 if (!codec_mgr) {
368 pj_pool_release(ipp_factory.pool);
369 ipp_factory.pool = NULL;
370 return PJ_EINVALIDOP;
371 }
372
373 /* Unregister IPP codecs factory. */
374 status = pjmedia_codec_mgr_unregister_factory(codec_mgr,
375 &ipp_factory.base);
376
377 /* Destroy mutex. */
378 pj_mutex_destroy(ipp_factory.mutex);
379
380 /* Destroy pool. */
381 pj_pool_release(ipp_factory.pool);
382 ipp_factory.pool = NULL;
383
384 return status;
385}
386
387/*
388 * Check if factory can allocate the specified codec.
389 */
390static pj_status_t ipp_test_alloc( pjmedia_codec_factory *factory,
391 const pjmedia_codec_info *info )
392{
393 unsigned i;
394
395 PJ_UNUSED_ARG(factory);
396
397 /* Type MUST be audio. */
398 if (info->type != PJMEDIA_TYPE_AUDIO)
399 return PJMEDIA_CODEC_EUNSUP;
400
401 for (i = 0; i < PJ_ARRAY_SIZE(ipp_codec); ++i) {
402 pj_str_t name = pj_str((char*)ipp_codec[i].name);
403 if ((pj_stricmp(&info->encoding_name, &name) == 0) &&
404 (info->clock_rate == (unsigned)ipp_codec[i].clock_rate) &&
405 (info->channel_cnt == (unsigned)ipp_codec[i].channel_count) &&
406 (ipp_codec[i].enabled))
407 {
408 return PJ_SUCCESS;
409 }
410 }
411
412 /* Unsupported, or mode is disabled. */
413 return PJMEDIA_CODEC_EUNSUP;
414}
415
416/*
417 * Generate default attribute.
418 */
419static pj_status_t ipp_default_attr (pjmedia_codec_factory *factory,
420 const pjmedia_codec_info *id,
421 pjmedia_codec_param *attr )
422{
423 unsigned i;
424
425 PJ_ASSERT_RETURN(factory==&ipp_factory.base, PJ_EINVAL);
426
427 pj_bzero(attr, sizeof(pjmedia_codec_param));
428
429 for (i = 0; i < PJ_ARRAY_SIZE(ipp_codec); ++i) {
430 pj_str_t name = pj_str((char*)ipp_codec[i].name);
431 if ((pj_stricmp(&id->encoding_name, &name) == 0) &&
432 (id->clock_rate == (unsigned)ipp_codec[i].clock_rate) &&
Nanang Izzuddin23a00b72008-08-25 13:58:25 +0000433 (id->channel_cnt == (unsigned)ipp_codec[i].channel_count) &&
434 (id->pt == (unsigned)ipp_codec[i].pt))
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000435 {
436 attr->info.pt = (pj_uint8_t)id->pt;
437 attr->info.channel_cnt = ipp_codec[i].channel_count;
438 attr->info.clock_rate = ipp_codec[i].clock_rate;
439 attr->info.avg_bps = ipp_codec[i].def_bitrate;
440 attr->info.max_bps = ipp_codec[i].max_bitrate;
441 attr->info.pcm_bits_per_sample = 16;
442 attr->info.frm_ptime = (pj_uint16_t)
443 (ipp_codec[i].samples_per_frame * 1000 /
444 ipp_codec[i].channel_count /
445 ipp_codec[i].clock_rate);
446 attr->setting.frm_per_pkt = ipp_codec[i].frm_per_pkt;
447
448 /* Default flags. */
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000449 attr->setting.plc = 1;
450 attr->setting.penh= 0;
Nanang Izzuddin23a00b72008-08-25 13:58:25 +0000451 attr->setting.vad = 1;
452 attr->setting.cng = attr->setting.vad;
453 attr->setting.dec_fmtp = ipp_codec[i].dec_fmtp;
454
455 if (attr->setting.vad == 0) {
456#if PJMEDIA_HAS_INTEL_IPP_CODEC_G729
457 if (id->pt == PJMEDIA_RTP_PT_G729) {
458 /* Signal G729 Annex B is being disabled */
459 attr->setting.dec_fmtp.cnt = 1;
460 pj_strset2(&attr->setting.dec_fmtp.param[0].name, "annexb");
461 pj_strset2(&attr->setting.dec_fmtp.param[0].val, "no");
462 }
463#endif
464 }
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000465
466 return PJ_SUCCESS;
467 }
468 }
469
470 return PJMEDIA_CODEC_EUNSUP;
471}
472
473/*
474 * Enum codecs supported by this factory.
475 */
476static pj_status_t ipp_enum_codecs(pjmedia_codec_factory *factory,
477 unsigned *count,
478 pjmedia_codec_info codecs[])
479{
480 unsigned max;
481 unsigned i;
482
483 PJ_UNUSED_ARG(factory);
484 PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);
485
486 max = *count;
487
488 for (i = 0, *count = 0; i < PJ_ARRAY_SIZE(ipp_codec) && *count < max; ++i)
489 {
490 if (!ipp_codec[i].enabled)
491 continue;
492
493 pj_bzero(&codecs[*count], sizeof(pjmedia_codec_info));
494 codecs[*count].encoding_name = pj_str((char*)ipp_codec[i].name);
495 codecs[*count].pt = ipp_codec[i].pt;
496 codecs[*count].type = PJMEDIA_TYPE_AUDIO;
497 codecs[*count].clock_rate = ipp_codec[i].clock_rate;
498 codecs[*count].channel_cnt = ipp_codec[i].channel_count;
499
500 ++*count;
501 }
502
503 return PJ_SUCCESS;
504}
505
506/*
507 * Allocate a new codec instance.
508 */
509static pj_status_t ipp_alloc_codec( pjmedia_codec_factory *factory,
510 const pjmedia_codec_info *id,
511 pjmedia_codec **p_codec)
512{
513 ipp_private_t *codec_data;
514 pjmedia_codec *codec;
515 int idx;
516 pj_pool_t *pool;
517 unsigned i;
518
519 PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);
520 PJ_ASSERT_RETURN(factory == &ipp_factory.base, PJ_EINVAL);
521
522 pj_mutex_lock(ipp_factory.mutex);
523
524 /* Find codec's index */
525 idx = -1;
526 for (i = 0; i < PJ_ARRAY_SIZE(ipp_codec); ++i) {
527 pj_str_t name = pj_str((char*)ipp_codec[i].name);
528 if ((pj_stricmp(&id->encoding_name, &name) == 0) &&
529 (id->clock_rate == (unsigned)ipp_codec[i].clock_rate) &&
530 (id->channel_cnt == (unsigned)ipp_codec[i].channel_count) &&
531 (ipp_codec[i].enabled))
532 {
533 idx = i;
534 break;
535 }
536 }
537 if (idx == -1) {
538 *p_codec = NULL;
539 return PJMEDIA_CODEC_EFAILED;
540 }
541
542 /* Create pool for codec instance */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000543 pool = pjmedia_endpt_create_pool(ipp_factory.endpt, "IPPcodec", 512, 512);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000544 codec = PJ_POOL_ZALLOC_T(pool, pjmedia_codec);
545 PJ_ASSERT_RETURN(codec != NULL, PJ_ENOMEM);
546 codec->op = &ipp_op;
547 codec->factory = factory;
548 codec->codec_data = PJ_POOL_ZALLOC_T(pool, ipp_private_t);
549 codec_data = (ipp_private_t*) codec->codec_data;
550
551 /* Create PLC if codec has no internal PLC */
552 if (!ipp_codec[idx].has_native_plc) {
553 pj_status_t status;
554 status = pjmedia_plc_create(pool, ipp_codec[idx].clock_rate,
555 ipp_codec[idx].samples_per_frame, 0,
556 &codec_data->plc);
557 if (status != PJ_SUCCESS) {
558 pj_pool_release(pool);
559 pj_mutex_unlock(ipp_factory.mutex);
560 return status;
561 }
562 }
563
564 /* Create silence detector if codec has no internal VAD */
565 if (!ipp_codec[idx].has_native_vad) {
566 pj_status_t status;
567 status = pjmedia_silence_det_create(pool,
568 ipp_codec[idx].clock_rate,
569 ipp_codec[idx].samples_per_frame,
570 &codec_data->vad);
571 if (status != PJ_SUCCESS) {
572 pj_pool_release(pool);
573 pj_mutex_unlock(ipp_factory.mutex);
574 return status;
575 }
576 }
577
578 codec_data->pool = pool;
579 codec_data->codec_idx = idx;
580
581 pj_mutex_unlock(ipp_factory.mutex);
582
583 *p_codec = codec;
584 return PJ_SUCCESS;
585}
586
587/*
588 * Free codec.
589 */
590static pj_status_t ipp_dealloc_codec( pjmedia_codec_factory *factory,
591 pjmedia_codec *codec )
592{
593 ipp_private_t *codec_data;
594
595 PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);
596 PJ_ASSERT_RETURN(factory == &ipp_factory.base, PJ_EINVAL);
597
598 /* Close codec, if it's not closed. */
599 codec_data = (ipp_private_t*) codec->codec_data;
600 if (codec_data->enc != NULL || codec_data->dec != NULL) {
601 ipp_codec_close(codec);
602 }
603
604 pj_pool_release(codec_data->pool);
605
606 return PJ_SUCCESS;
607}
608
609/*
610 * Init codec.
611 */
612static pj_status_t ipp_codec_init( pjmedia_codec *codec,
613 pj_pool_t *pool )
614{
615 PJ_UNUSED_ARG(codec);
616 PJ_UNUSED_ARG(pool);
617 return PJ_SUCCESS;
618}
619
620/*
621 * Open codec.
622 */
623static pj_status_t ipp_codec_open( pjmedia_codec *codec,
624 pjmedia_codec_param *attr )
625{
626 ipp_private_t *codec_data = (ipp_private_t*) codec->codec_data;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000627 struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000628 int info_size;
629 pj_pool_t *pool;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000630 int i, j;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000631 USC_MemBank *membanks;
632 int nb_membanks;
633
634 pool = codec_data->pool;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000635
636 /* Get the codec info size */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000637 if (USC_NoError != ippc->fxns->std.GetInfoSize(&info_size)) {
638 PJ_LOG(1,(THIS_FILE, "Error getting codec info size"));
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000639 goto on_error;
640 }
641 /* Get the codec info */
642 codec_data->info = pj_pool_zalloc(pool, info_size);
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000643 if (USC_NoError != ippc->fxns->std.GetInfo((USC_Handle)NULL,
644 codec_data->info))
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000645 {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000646 PJ_LOG(1,(THIS_FILE, "Error getting codec info"));
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000647 goto on_error;
648 }
649
650 /* PREPARING THE ENCODER */
651
652 /* Setting the encoder params */
653 codec_data->info->params.direction = USC_ENCODE;
Nanang Izzuddinf216f822008-08-15 18:35:50 +0000654 codec_data->info->params.modes.vad = attr->setting.vad &&
Nanang Izzuddin23a00b72008-08-25 13:58:25 +0000655 ippc->has_native_vad;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000656 codec_data->info->params.modes.bitrate = attr->info.avg_bps;
657 codec_data->info->params.law = 0; /* Linear PCM input */
658
Nanang Izzuddin23a00b72008-08-25 13:58:25 +0000659#if PJMEDIA_HAS_INTEL_IPP_CODEC_G729
660 if (ippc->pt == PJMEDIA_RTP_PT_G729) {
661 /* Check if G729 Annex B is signaled to be disabled */
662 for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) {
663 if (pj_stricmp2(&attr->setting.enc_fmtp.param[i].name, "annexb")==0)
664 {
665 if (pj_stricmp2(&attr->setting.enc_fmtp.param[i].val, "no")==0)
666 codec_data->info->params.modes.vad = 0;
667 break;
668 }
669 }
670 }
671#endif
672
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000673 /* Get number of memory blocks needed by the encoder */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000674 if (USC_NoError != ippc->fxns->std.NumAlloc(&codec_data->info->params,
675 &nb_membanks))
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000676 {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000677 PJ_LOG(1,(THIS_FILE, "Error getting no of memory blocks of encoder"));
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000678 goto on_error;
679 }
680
681 /* Allocate memory blocks table */
682 membanks = (USC_MemBank*) pj_pool_zalloc(pool,
683 sizeof(USC_MemBank) * nb_membanks);
684 /* Get size of each memory block */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000685 if (USC_NoError != ippc->fxns->std.MemAlloc(&codec_data->info->params,
686 membanks))
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000687 {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000688 PJ_LOG(1,(THIS_FILE, "Error getting memory blocks size of encoder"));
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000689 goto on_error;
690 }
691
692 /* Allocate memory for each block */
693 for (i = 0; i < nb_membanks; i++) {
694 membanks[i].pMem = (char*) pj_pool_zalloc(pool, membanks[i].nbytes);
695 }
696
697 /* Create encoder instance */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000698 if (USC_NoError != ippc->fxns->std.Init(&codec_data->info->params,
699 membanks,
700 &codec_data->enc))
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000701 {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000702 PJ_LOG(1,(THIS_FILE, "Error initializing encoder"));
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000703 goto on_error;
704 }
705
706 /* PREPARING THE DECODER */
707
708 /* Setting the decoder params */
709 codec_data->info->params.direction = USC_DECODE;
710
Nanang Izzuddin23a00b72008-08-25 13:58:25 +0000711 /* Not sure if VAD affects decoder, just try to be safe */
712 codec_data->info->params.modes.vad = ippc->has_native_vad;
713
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000714 /* Get number of memory blocks needed by the decoder */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000715 if (USC_NoError != ippc->fxns->std.NumAlloc(&codec_data->info->params,
716 &nb_membanks))
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000717 {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000718 PJ_LOG(1,(THIS_FILE, "Error getting no of memory blocks of decoder"));
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000719 goto on_error;
720 }
721
722 /* Allocate memory blocks table */
723 membanks = (USC_MemBank*) pj_pool_zalloc(pool,
724 sizeof(USC_MemBank) * nb_membanks);
725 /* Get size of each memory block */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000726 if (USC_NoError != ippc->fxns->std.MemAlloc(&codec_data->info->params,
727 membanks))
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000728 {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000729 PJ_LOG(1,(THIS_FILE, "Error getting memory blocks size of decoder"));
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000730 goto on_error;
731 }
732
733 /* Allocate memory for each block */
734 for (i = 0; i < nb_membanks; i++) {
735 membanks[i].pMem = (char*) pj_pool_zalloc(pool, membanks[i].nbytes);
736 }
737
738 /* Create decoder instance */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000739 if (USC_NoError != ippc->fxns->std.Init(&codec_data->info->params,
740 membanks, &codec_data->dec))
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000741 {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000742 PJ_LOG(1,(THIS_FILE, "Error initializing decoder"));
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000743 goto on_error;
744 }
745
746 /* Update codec info */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000747 ippc->fxns->std.GetInfo((USC_Handle)codec_data->enc, codec_data->info);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000748
749 /* Get bitstream size */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000750 i = codec_data->info->params.modes.bitrate * ippc->samples_per_frame;
751 j = ippc->clock_rate << 3;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000752 codec_data->frame_size = (pj_uint16_t)(i / j);
753 if (i % j) ++codec_data->frame_size;
754
755 codec_data->vad_enabled = (attr->setting.vad != 0);
756 codec_data->plc_enabled = (attr->setting.plc != 0);
757
758 return PJ_SUCCESS;
759
760on_error:
761 return PJMEDIA_CODEC_EFAILED;
762}
763
764/*
765 * Close codec.
766 */
767static pj_status_t ipp_codec_close( pjmedia_codec *codec )
768{
769 PJ_UNUSED_ARG(codec);
770
771 return PJ_SUCCESS;
772}
773
774
775/*
776 * Modify codec settings.
777 */
778static pj_status_t ipp_codec_modify(pjmedia_codec *codec,
779 const pjmedia_codec_param *attr )
780{
781 ipp_private_t *codec_data = (ipp_private_t*) codec->codec_data;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000782 struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000783
784 codec_data->vad_enabled = (attr->setting.vad != 0);
785 codec_data->plc_enabled = (attr->setting.plc != 0);
786
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000787 if (ippc->has_native_vad) {
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000788 USC_Modes modes;
789
790 modes = codec_data->info->params.modes;
791 modes.vad = codec_data->vad_enabled;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000792 ippc->fxns->std.Control(&modes, codec_data->enc);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000793 }
794
795 return PJ_SUCCESS;
796}
797
798/*
799 * Get frames in the packet.
800 */
801static pj_status_t ipp_codec_parse( pjmedia_codec *codec,
802 void *pkt,
803 pj_size_t pkt_size,
804 const pj_timestamp *ts,
805 unsigned *frame_cnt,
806 pjmedia_frame frames[])
807{
808 ipp_private_t *codec_data = (ipp_private_t*) codec->codec_data;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000809 struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000810 unsigned count = 0;
811
812 PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);
813
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000814 if (ippc->parse != NULL) {
815 return ippc->parse(codec_data, pkt, pkt_size, ts, frame_cnt, frames);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000816 }
817
818 while (pkt_size >= codec_data->frame_size && count < *frame_cnt) {
819 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;
820 frames[count].buf = pkt;
821 frames[count].size = codec_data->frame_size;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000822 frames[count].timestamp.u64 = ts->u64 + count*ippc->samples_per_frame;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000823
824 pkt = ((char*)pkt) + codec_data->frame_size;
825 pkt_size -= codec_data->frame_size;
826
827 ++count;
828 }
829
830 if (pkt_size && count < *frame_cnt) {
831 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;
832 frames[count].buf = pkt;
833 frames[count].size = pkt_size;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000834 frames[count].timestamp.u64 = ts->u64 + count*ippc->samples_per_frame;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000835 ++count;
836 }
837
838 *frame_cnt = count;
839 return PJ_SUCCESS;
840}
841
842/*
843 * Encode frames.
844 */
845static pj_status_t ipp_codec_encode( pjmedia_codec *codec,
846 const struct pjmedia_frame *input,
847 unsigned output_buf_len,
848 struct pjmedia_frame *output)
849{
850 ipp_private_t *codec_data = (ipp_private_t*) codec->codec_data;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000851 struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000852 unsigned samples_per_frame;
853 unsigned nsamples;
854 pj_size_t tx = 0;
855 pj_int16_t *pcm_in = (pj_int16_t*)input->buf;
Benny Prijonob1339242008-08-21 20:58:55 +0000856 pj_uint8_t *bits_out = (pj_uint8_t*) output->buf;
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000857 pj_uint8_t pt;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000858
859 /* Invoke external VAD if codec has no internal VAD */
860 if (codec_data->vad && codec_data->vad_enabled) {
861 pj_bool_t is_silence;
862 pj_int32_t silence_duration;
863
864 silence_duration = pj_timestamp_diff32(&codec_data->last_tx,
865 &input->timestamp);
866
867 is_silence = pjmedia_silence_det_detect(codec_data->vad,
868 (const pj_int16_t*) input->buf,
869 (input->size >> 1),
870 NULL);
871 if (is_silence &&
872 PJMEDIA_CODEC_MAX_SILENCE_PERIOD != -1 &&
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000873 silence_duration < (PJMEDIA_CODEC_MAX_SILENCE_PERIOD *
874 (int)ippc->clock_rate / 1000))
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000875 {
876 output->type = PJMEDIA_FRAME_TYPE_NONE;
877 output->buf = NULL;
878 output->size = 0;
879 output->timestamp = input->timestamp;
880 return PJ_SUCCESS;
881 } else {
882 codec_data->last_tx = input->timestamp;
883 }
884 }
885
886 nsamples = input->size >> 1;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000887 samples_per_frame = ippc->samples_per_frame;
888 pt = ippc->pt;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000889
890 PJ_ASSERT_RETURN(nsamples % samples_per_frame == 0,
891 PJMEDIA_CODEC_EPCMFRMINLEN);
892
893 /* Encode the frames */
894 while (nsamples >= samples_per_frame) {
895 USC_PCMStream in;
896 USC_Bitstream out;
897
898 in.bitrate = codec_data->info->params.modes.bitrate;
899 in.nbytes = samples_per_frame << 1;
900 in.pBuffer = (char*)pcm_in;
901 in.pcmType.bitPerSample = codec_data->info->params.pcmType.bitPerSample;
902 in.pcmType.nChannels = codec_data->info->params.pcmType.nChannels;
903 in.pcmType.sample_frequency = codec_data->info->params.pcmType.sample_frequency;
904
Benny Prijonob1339242008-08-21 20:58:55 +0000905 out.pBuffer = (char*)bits_out;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000906
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000907#if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000908 /* For AMR: reserve the first byte for frame info */
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000909 if (pt == PJMEDIA_RTP_PT_AMR || pt == PJMEDIA_RTP_PT_AMRWB) {
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000910 ++out.pBuffer;
911 }
912#endif
913
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000914 if (USC_NoError != ippc->fxns->Encode(codec_data->enc, &in, &out)) {
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000915 break;
916 }
917
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000918#if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
919 /* For AMR: put info (frametype, degraded, last frame) in the
920 * first byte
921 */
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000922 if (pt == PJMEDIA_RTP_PT_AMR || pt == PJMEDIA_RTP_PT_AMRWB) {
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000923 pj_uint8_t *info = (pj_uint8_t*)bits_out;
924
925 ++out.nbytes;
926
927 /* One byte AMR frame type & quality flag:
928 * bit 0-3 : frame type
929 * bit 6 : last frame flag
930 * bit 7 : quality flag
931 */
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000932 if (out.frametype == 0 || out.frametype == 4 ||
933 (pt == PJMEDIA_RTP_PT_AMR && out.frametype == 5) ||
934 (pt == PJMEDIA_RTP_PT_AMRWB && out.frametype == 6))
935 {
936 /* Speech */
937 *info = (char)amr_get_mode(out.bitrate);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000938 /* Degraded */
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000939 if (out.frametype == 5 || out.frametype == 6)
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000940 *info |= 0x80;
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000941 } else if (out.frametype == 1 || out.frametype == 2 ||
942 (pt == PJMEDIA_RTP_PT_AMR && out.frametype == 6) ||
943 (pt == PJMEDIA_RTP_PT_AMRWB && out.frametype == 7))
944 {
945 /* SID */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000946 *info = (pj_uint8_t)(pt == PJMEDIA_RTP_PT_AMRWB? 9 : 8);
Nanang Izzuddindf361e02008-08-16 06:46:08 +0000947 /* Degraded */
948 if (out.frametype == 6 || out.frametype == 7)
949 *info |= 0x80;
950 } else {
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000951 /* Untransmited */
952 *info = 15;
953 out.nbytes = 1;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000954 }
955
956 /* Last frame flag */
957 if (nsamples == samples_per_frame)
958 *info |= 0x40;
959 }
Nanang Izzuddin7dd32682008-08-19 11:23:33 +0000960#endif
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000961
962 pcm_in += samples_per_frame;
963 nsamples -= samples_per_frame;
964 tx += out.nbytes;
965 bits_out += out.nbytes;
Nanang Izzuddin23a00b72008-08-25 13:58:25 +0000966
967#if PJMEDIA_HAS_INTEL_IPP_CODEC_G729
968 if (out.frametype == 1) {
969 /* SID */
970 break;
971 } else if (out.frametype == 0) {
972 /* Untransmitted */
973 tx -= out.nbytes;
974 break;
975 }
976#endif
977
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000978 }
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000979
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000980 if (ippc->pack != NULL) {
981 ippc->pack(codec_data, output->buf, &tx, output_buf_len);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000982 }
983
984 /* Check if we don't need to transmit the frame (DTX) */
985 if (tx == 0) {
986 output->buf = NULL;
987 output->size = 0;
988 output->timestamp.u64 = input->timestamp.u64;
989 output->type = PJMEDIA_FRAME_TYPE_NONE;
990 return PJ_SUCCESS;
991 }
992
993 output->size = tx;
994 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
995 output->timestamp = input->timestamp;
996
997 return PJ_SUCCESS;
998}
999
1000/*
1001 * Decode frame.
1002 */
1003static pj_status_t ipp_codec_decode( pjmedia_codec *codec,
1004 const struct pjmedia_frame *input,
1005 unsigned output_buf_len,
1006 struct pjmedia_frame *output)
1007{
1008 ipp_private_t *codec_data = (ipp_private_t*) codec->codec_data;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001009 struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001010 unsigned samples_per_frame;
1011 USC_PCMStream out;
1012 USC_Bitstream in;
1013 pj_uint8_t pt;
1014
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001015 pt = ippc->pt;
1016 samples_per_frame = ippc->samples_per_frame;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001017
1018 PJ_ASSERT_RETURN(output_buf_len >= samples_per_frame << 1,
1019 PJMEDIA_CODEC_EPCMTOOSHORT);
1020
1021 if (input->type == PJMEDIA_FRAME_TYPE_AUDIO) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001022 if (ippc->predecode) {
1023 ippc->predecode(codec_data, input, &in);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001024 } else {
1025 /* Most IPP codecs have frametype==0 for speech frame */
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001026 in.pBuffer = (char*)input->buf;
1027 in.nbytes = input->size;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001028 in.frametype = 0;
1029 in.bitrate = codec_data->info->params.modes.bitrate;
1030 }
1031
1032 out.pBuffer = output->buf;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001033 }
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001034
1035 if (input->type != PJMEDIA_FRAME_TYPE_AUDIO ||
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001036 USC_NoError != ippc->fxns->Decode(codec_data->dec, &in, &out))
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001037 {
1038 pjmedia_zero_samples((pj_int16_t*)output->buf, samples_per_frame);
1039 output->size = samples_per_frame << 1;
1040 output->timestamp.u64 = input->timestamp.u64;
1041 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
1042 return PJ_SUCCESS;
1043 }
1044
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001045#if PJMEDIA_HAS_INTEL_IPP_CODEC_G726
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001046 /* For G.726: amplify decoding result (USC G.726 encoder deamplified it) */
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001047 if (pt == PJMEDIA_RTP_PT_G726_16 || pt == PJMEDIA_RTP_PT_G726_24 ||
1048 pt == PJMEDIA_RTP_PT_G726_32 || pt == PJMEDIA_RTP_PT_G726_40)
1049 {
1050 unsigned i;
1051 pj_int16_t *s = (pj_int16_t*)output->buf;
1052
1053 for (i = 0; i < samples_per_frame; ++i)
1054 s[i] <<= 2;
1055 }
1056#endif
1057
1058 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
1059 output->size = samples_per_frame << 1;
1060 output->timestamp.u64 = input->timestamp.u64;
1061
1062 /* Invoke external PLC if codec has no internal PLC */
1063 if (codec_data->plc && codec_data->plc_enabled)
1064 pjmedia_plc_save(codec_data->plc, (pj_int16_t*)output->buf);
1065
1066 return PJ_SUCCESS;
1067}
1068
1069/*
1070 * Recover lost frame.
1071 */
1072static pj_status_t ipp_codec_recover(pjmedia_codec *codec,
1073 unsigned output_buf_len,
1074 struct pjmedia_frame *output)
1075{
1076 ipp_private_t *codec_data = (ipp_private_t*) codec->codec_data;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001077 struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001078 unsigned samples_per_frame;
1079
1080 PJ_UNUSED_ARG(output_buf_len);
1081
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001082 samples_per_frame = ippc->samples_per_frame;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001083
1084 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
1085 output->size = samples_per_frame << 1;
1086
1087 if (codec_data->plc_enabled) {
1088 if (codec_data->plc) {
1089 pjmedia_plc_generate(codec_data->plc, (pj_int16_t*)output->buf);
1090 } else {
1091 USC_PCMStream out;
1092 out.pBuffer = output->buf;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001093 ippc->fxns->Decode(codec_data->dec, NULL, &out);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001094 }
1095 } else {
1096 pjmedia_zero_samples((pj_int16_t*)output->buf, samples_per_frame);
1097 }
1098
1099 return PJ_SUCCESS;
1100}
1101
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001102#if PJMEDIA_HAS_INTEL_IPP_CODEC_G729
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001103
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001104static void predecode_g729( ipp_private_t *codec_data,
1105 const pjmedia_frame *rtp_frame,
1106 USC_Bitstream *usc_frame)
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001107{
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001108 switch (rtp_frame->size) {
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001109 case 2:
1110 /* SID */
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001111 usc_frame->frametype = 1;
1112 usc_frame->bitrate = codec_data->info->params.modes.bitrate;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001113 break;
1114 case 8:
1115 /* G729D */
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001116 usc_frame->frametype = 2;
1117 usc_frame->bitrate = 6400;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001118 break;
1119 case 10:
1120 /* G729 */
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001121 usc_frame->frametype = 3;
1122 usc_frame->bitrate = 8000;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001123 break;
1124 case 15:
1125 /* G729E */
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001126 usc_frame->frametype = 4;
1127 usc_frame->bitrate = 11800;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001128 break;
1129 default:
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001130 usc_frame->frametype = 0;
1131 usc_frame->bitrate = 0;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001132 break;
1133 }
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001134
1135 usc_frame->pBuffer = rtp_frame->buf;
1136 usc_frame->nbytes = rtp_frame->size;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001137}
1138
1139#endif /* PJMEDIA_HAS_INTEL_IPP_CODEC_G729 */
1140
1141
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001142#if PJMEDIA_HAS_INTEL_IPP_CODEC_G723_1
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001143
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001144static void predecode_g723( ipp_private_t *codec_data,
1145 const pjmedia_frame *rtp_frame,
1146 USC_Bitstream *usc_frame)
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001147{
1148 int i, HDR = 0;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001149 pj_uint8_t *f = (pj_uint8_t*)rtp_frame->buf;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001150
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001151 PJ_UNUSED_ARG(codec_data);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001152
1153 for (i = 0; i < 2; ++i){
1154 int tmp;
1155 tmp = (f[0] >> (i & 0x7)) & 1;
1156 HDR += tmp << i ;
1157 }
1158
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001159 usc_frame->pBuffer = rtp_frame->buf;
1160 usc_frame->nbytes = rtp_frame->size;
1161 usc_frame->bitrate = HDR == 0? 6300 : 5300;
1162 usc_frame->frametype = 0;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001163}
1164
1165static pj_status_t parse_g723(ipp_private_t *codec_data, void *pkt,
1166 pj_size_t pkt_size, const pj_timestamp *ts,
1167 unsigned *frame_cnt, pjmedia_frame frames[])
1168{
1169 unsigned count = 0;
1170 pj_uint8_t *f = (pj_uint8_t*)pkt;
1171
1172 while (pkt_size && count < *frame_cnt) {
1173 int framesize, i, j;
1174 int HDR = 0;
1175
1176 for (i = 0; i < 2; ++i){
1177 j = (f[0] >> (i & 0x7)) & 1;
1178 HDR += j << i ;
1179 }
1180
1181 if (HDR == 0)
1182 framesize = 24;
1183 else if (HDR == 1)
1184 framesize = 20;
1185 else if (HDR == 2)
1186 framesize = 4;
1187 else if (HDR == 3)
1188 framesize = 1;
1189 else {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001190 pj_assert(!"Unknown G723.1 frametype, packet may be corrupted!");
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001191 return PJMEDIA_CODEC_EINMODE;
1192 }
1193
1194 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;
1195 frames[count].buf = f;
1196 frames[count].size = framesize;
1197 frames[count].timestamp.u64 = ts->u64 + count *
1198 ipp_codec[codec_data->codec_idx].samples_per_frame;
1199
1200 f += framesize;
1201 pkt_size -= framesize;
1202
1203 ++count;
1204 }
1205
1206 *frame_cnt = count;
1207 return PJ_SUCCESS;
1208}
1209
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001210#endif /* PJMEDIA_HAS_INTEL_IPP_CODEC_G723_1 */
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001211
1212
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001213#if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001214
1215/* AMR bitstream sensitivity order map */
1216static pj_int16_t AMRNB_ordermap122[244] =
1217{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001218 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1219 10, 11, 12, 13, 14, 23, 15, 16, 17, 18,
1220 19, 20, 21, 22, 24, 25, 26, 27, 28, 38,
1221 141, 39, 142, 40, 143, 41, 144, 42, 145, 43,
1222 146, 44, 147, 45, 148, 46, 149, 47, 97, 150,
1223 200, 48, 98, 151, 201, 49, 99, 152, 202, 86,
1224 136, 189, 239, 87, 137, 190, 240, 88, 138, 191,
1225 241, 91, 194, 92, 195, 93, 196, 94, 197, 95,
1226 198, 29, 30, 31, 32, 33, 34, 35, 50, 100,
1227 153, 203, 89, 139, 192, 242, 51, 101, 154, 204,
1228 55, 105, 158, 208, 90, 140, 193, 243, 59, 109,
1229 162, 212, 63, 113, 166, 216, 67, 117, 170, 220,
1230 36, 37, 54, 53, 52, 58, 57, 56, 62, 61,
1231 60, 66, 65, 64, 70, 69, 68, 104, 103, 102,
1232 108, 107, 106, 112, 111, 110, 116, 115, 114, 120,
1233 119, 118, 157, 156, 155, 161, 160, 159, 165, 164,
1234 163, 169, 168, 167, 173, 172, 171, 207, 206, 205,
1235 211, 210, 209, 215, 214, 213, 219, 218, 217, 223,
1236 222, 221, 73, 72, 71, 76, 75, 74, 79, 78,
1237 77, 82, 81, 80, 85, 84, 83, 123, 122, 121,
1238 126, 125, 124, 129, 128, 127, 132, 131, 130, 135,
1239 134, 133, 176, 175, 174, 179, 178, 177, 182, 181,
1240 180, 185, 184, 183, 188, 187, 186, 226, 225, 224,
1241 229, 228, 227, 232, 231, 230, 235, 234, 233, 238,
1242 237, 236, 96, 199
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001243};
1244
1245static pj_int16_t AMRNB_ordermap102[204] =
1246{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001247 7, 6, 5, 4, 3, 2, 1, 0, 16, 15,
1248 14, 13, 12, 11, 10, 9, 8, 26, 27, 28,
1249 29, 30, 31, 115, 116, 117, 118, 119, 120, 72,
1250 73, 161, 162, 65, 68, 69, 108, 111, 112, 154,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001251 157, 158, 197, 200, 201, 32, 33, 121, 122, 74,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001252 75, 163, 164, 66, 109, 155, 198, 19, 23, 21,
1253 22, 18, 17, 20, 24, 25, 37, 36, 35, 34,
1254 80, 79, 78, 77, 126, 125, 124, 123, 169, 168,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001255 167, 166, 70, 67, 71, 113, 110, 114, 159, 156,
1256 160, 202, 199, 203, 76, 165, 81, 82, 92, 91,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001257 93, 83, 95, 85, 84, 94, 101, 102, 96, 104,
1258 86, 103, 87, 97, 127, 128, 138, 137, 139, 129,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001259 141, 131, 130, 140, 147, 148, 142, 150, 132, 149,
1260 133, 143, 170, 171, 181, 180, 182, 172, 184, 174,
1261 173, 183, 190, 191, 185, 193, 175, 192, 176, 186,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001262 38, 39, 49, 48, 50, 40, 52, 42, 41, 51,
1263 58, 59, 53, 61, 43, 60, 44, 54, 194, 179,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001264 189, 196, 177, 195, 178, 187, 188, 151, 136, 146,
1265 153, 134, 152, 135, 144, 145, 105, 90, 100, 107,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001266 88, 106, 89, 98, 99, 62, 47, 57, 64, 45,
1267 63, 46, 55, 56
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001268};
1269
1270static pj_int16_t AMRNB_ordermap795[159] =
1271{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001272 8, 7, 6, 5, 4, 3, 2, 14, 16, 9,
1273 10, 12, 13, 15, 11, 17, 20, 22, 24, 23,
1274 19, 18, 21, 56, 88, 122, 154, 57, 89, 123,
1275 155, 58, 90, 124, 156, 52, 84, 118, 150, 53,
1276 85, 119, 151, 27, 93, 28, 94, 29, 95, 30,
1277 96, 31, 97, 61, 127, 62, 128, 63, 129, 59,
1278 91, 125, 157, 32, 98, 64, 130, 1, 0, 25,
1279 26, 33, 99, 34, 100, 65, 131, 66, 132, 54,
1280 86, 120, 152, 60, 92, 126, 158, 55, 87, 121,
1281 153, 117, 116, 115, 46, 78, 112, 144, 43, 75,
1282 109, 141, 40, 72, 106, 138, 36, 68, 102, 134,
1283 114, 149, 148, 147, 146, 83, 82, 81, 80, 51,
1284 50, 49, 48, 47, 45, 44, 42, 39, 35, 79,
1285 77, 76, 74, 71, 67, 113, 111, 110, 108, 105,
1286 101, 145, 143, 142, 140, 137, 133, 41, 73, 107,
1287 139, 37, 69, 103, 135, 38, 70, 104, 136
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001288
1289};
1290
1291static pj_int16_t AMRNB_ordermap74[148] =
1292{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001293 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1294 10, 11, 12, 13, 14, 15, 16, 26, 87, 27,
1295 88, 28, 89, 29, 90, 30, 91, 51, 80, 112,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001296 141, 52, 81, 113, 142, 54, 83, 115, 144, 55,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001297 84, 116, 145, 58, 119, 59, 120, 21, 22, 23,
1298 17, 18, 19, 31, 60, 92, 121, 56, 85, 117,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001299 146, 20, 24, 25, 50, 79, 111, 140, 57, 86,
1300 118, 147, 49, 78, 110, 139, 48, 77, 53, 82,
1301 114, 143, 109, 138, 47, 76, 108, 137, 32, 33,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001302 61, 62, 93, 94, 122, 123, 41, 42, 43, 44,
1303 45, 46, 70, 71, 72, 73, 74, 75, 102, 103,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001304 104, 105, 106, 107, 131, 132, 133, 134, 135, 136,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001305 34, 63, 95, 124, 35, 64, 96, 125, 36, 65,
1306 97, 126, 37, 66, 98, 127, 38, 67, 99, 128,
1307 39, 68, 100, 129, 40, 69, 101, 130
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001308};
1309
1310static pj_int16_t AMRNB_ordermap67[134] =
1311{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001312 0, 1, 4, 3, 5, 6, 13, 7, 2, 8,
1313 9, 11, 15, 12, 14, 10, 28, 82, 29, 83,
1314 27, 81, 26, 80, 30, 84, 16, 55, 109, 56,
1315 110, 31, 85, 57, 111, 48, 73, 102, 127, 32,
1316 86, 51, 76, 105, 130, 52, 77, 106, 131, 58,
1317 112, 33, 87, 19, 23, 53, 78, 107, 132, 21,
1318 22, 18, 17, 20, 24, 25, 50, 75, 104, 129,
1319 47, 72, 101, 126, 54, 79, 108, 133, 46, 71,
1320 100, 125, 128, 103, 74, 49, 45, 70, 99, 124,
1321 42, 67, 96, 121, 39, 64, 93, 118, 38, 63,
1322 92, 117, 35, 60, 89, 114, 34, 59, 88, 113,
1323 44, 69, 98, 123, 43, 68, 97, 122, 41, 66,
1324 95, 120, 40, 65, 94, 119, 37, 62, 91, 116,
1325 36, 61, 90, 115
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001326};
1327
1328static pj_int16_t AMRNB_ordermap59[118] =
1329{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001330 0, 1, 4, 5, 3, 6, 7, 2, 13, 15,
1331 8, 9, 11, 12, 14, 10, 16, 28, 74, 29,
1332 75, 27, 73, 26, 72, 30, 76, 51, 97, 50,
1333 71, 96, 117, 31, 77, 52, 98, 49, 70, 95,
1334 116, 53, 99, 32, 78, 33, 79, 48, 69, 94,
1335 115, 47, 68, 93, 114, 46, 67, 92, 113, 19,
1336 21, 23, 22, 18, 17, 20, 24, 111, 43, 89,
1337 110, 64, 65, 44, 90, 25, 45, 66, 91, 112,
1338 54, 100, 40, 61, 86, 107, 39, 60, 85, 106,
1339 36, 57, 82, 103, 35, 56, 81, 102, 34, 55,
1340 80, 101, 42, 63, 88, 109, 41, 62, 87, 108,
1341 38, 59, 84, 105, 37, 58, 83, 104
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001342};
1343
1344static pj_int16_t AMRNB_ordermap515[103] =
1345{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001346 7, 6, 5, 4, 3, 2, 1, 0, 15, 14,
1347 13, 12, 11, 10, 9, 8, 23, 24, 25, 26,
1348 27, 46, 65, 84, 45, 44, 43, 64, 63, 62,
1349 83, 82, 81, 102, 101, 100, 42, 61, 80, 99,
1350 28, 47, 66, 85, 18, 41, 60, 79, 98, 29,
1351 48, 67, 17, 20, 22, 40, 59, 78, 97, 21,
1352 30, 49, 68, 86, 19, 16, 87, 39, 38, 58,
1353 57, 77, 35, 54, 73, 92, 76, 96, 95, 36,
1354 55, 74, 93, 32, 51, 33, 52, 70, 71, 89,
1355 90, 31, 50, 69, 88, 37, 56, 75, 94, 34,
1356 53, 72, 91
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001357};
1358
1359static pj_int16_t AMRNB_ordermap475[95] =
1360{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001361 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1362 10, 11, 12, 13, 14, 15, 23, 24, 25, 26,
1363 27, 28, 48, 49, 61, 62, 82, 83, 47, 46,
1364 45, 44, 81, 80, 79, 78, 17, 18, 20, 22,
1365 77, 76, 75, 74, 29, 30, 43, 42, 41, 40,
1366 38, 39, 16, 19, 21, 50, 51, 59, 60, 63,
1367 64, 72, 73, 84, 85, 93, 94, 32, 33, 35,
1368 36, 53, 54, 56, 57, 66, 67, 69, 70, 87,
1369 88, 90, 91, 34, 55, 68, 89, 37, 58, 71,
1370 92, 31, 52, 65, 86
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001371};
1372
1373static pj_int16_t *AMRNB_ordermaps[8] =
1374{
1375 AMRNB_ordermap475,
1376 AMRNB_ordermap515,
1377 AMRNB_ordermap59,
1378 AMRNB_ordermap67,
1379 AMRNB_ordermap74,
1380 AMRNB_ordermap795,
1381 AMRNB_ordermap102,
1382 AMRNB_ordermap122
1383};
1384
1385static pj_int16_t AMRWB_ordermap_660[] =
1386{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001387 0, 5, 6, 7, 61, 84, 107, 130, 62, 85,
1388 8, 4, 37, 38, 39, 40, 58, 81, 104, 127,
1389 60, 83, 106, 129, 108, 131, 128, 41, 42, 80,
1390 126, 1, 3, 57, 103, 82, 105, 59, 2, 63,
1391 109, 110, 86, 19, 22, 23, 64, 87, 18, 20,
1392 21, 17, 13, 88, 43, 89, 65, 111, 14, 24,
1393 25, 26, 27, 28, 15, 16, 44, 90, 66, 112,
1394 9, 11, 10, 12, 67, 113, 29, 30, 31, 32,
1395 34, 33, 35, 36, 45, 51, 68, 74, 91, 97,
1396 114, 120, 46, 69, 92, 115, 52, 75, 98, 121,
1397 47, 70, 93, 116, 53, 76, 99, 122, 48, 71,
1398 94, 117, 54, 77, 100, 123, 49, 72, 95, 118,
1399 55, 78, 101, 124, 50, 73, 96, 119, 56, 79,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001400 102, 125
1401};
1402
1403static pj_int16_t AMRWB_ordermap_885[] =
1404{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001405 0, 4, 6, 7, 5, 3, 47, 48, 49, 112,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001406 113, 114, 75, 106, 140, 171, 80, 111, 145, 176,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001407 77, 108, 142, 173, 78, 109, 143, 174, 79, 110,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001408 144, 175, 76, 107, 141, 172, 50, 115, 51, 2,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001409 1, 81, 116, 146, 19, 21, 12, 17, 18, 20,
1410 16, 25, 13, 10, 14, 24, 23, 22, 26, 8,
1411 15, 52, 117, 31, 82, 147, 9, 33, 11, 83,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001412 148, 53, 118, 28, 27, 84, 149, 34, 35, 29,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001413 46, 32, 30, 54, 119, 37, 36, 39, 38, 40,
1414 85, 150, 41, 42, 43, 44, 45, 55, 60, 65,
1415 70, 86, 91, 96, 101, 120, 125, 130, 135, 151,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001416 156, 161, 166, 56, 87, 121, 152, 61, 92, 126,
1417 157, 66, 97, 131, 162, 71, 102, 136, 167, 57,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001418 88, 122, 153, 62, 93, 127, 158, 67, 98, 132,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001419 163, 72, 103, 137, 168, 58, 89, 123, 154, 63,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001420 94, 128, 159, 68, 99, 133, 164, 73, 104, 138,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001421 169, 59, 90, 124, 155, 64, 95, 129, 160, 69,
1422 100, 134, 165, 74, 105, 139, 170
1423};
1424
1425static pj_int16_t AMRWB_ordermap_1265[] =
1426{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001427 0, 4, 6, 93, 143, 196, 246, 7, 5, 3,
1428 47, 48, 49, 50, 51, 150, 151, 152, 153, 154,
1429 94, 144, 197, 247, 99, 149, 202, 252, 96, 146,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001430 199, 249, 97, 147, 200, 250, 100, 203, 98, 148,
1431 201, 251, 95, 145, 198, 248, 52, 2, 1, 101,
1432 204, 155, 19, 21, 12, 17, 18, 20, 16, 25,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001433 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001434 156, 31, 102, 205, 9, 33, 11, 103, 206, 54,
1435 157, 28, 27, 104, 207, 34, 35, 29, 46, 32,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001436 30, 55, 158, 37, 36, 39, 38, 40, 105, 208,
1437 41, 42, 43, 44, 45, 56, 106, 159, 209, 57,
1438 66, 75, 84, 107, 116, 125, 134, 160, 169, 178,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001439 187, 210, 219, 228, 237, 58, 108, 161, 211, 62,
1440 112, 165, 215, 67, 117, 170, 220, 71, 121, 174,
1441 224, 76, 126, 179, 229, 80, 130, 183, 233, 85,
1442 135, 188, 238, 89, 139, 192, 242, 59, 109, 162,
1443 212, 63, 113, 166, 216, 68, 118, 171, 221, 72,
1444 122, 175, 225, 77, 127, 180, 230, 81, 131, 184,
1445 234, 86, 136, 189, 239, 90, 140, 193, 243, 60,
1446 110, 163, 213, 64, 114, 167, 217, 69, 119, 172,
1447 222, 73, 123, 176, 226, 78, 128, 181, 231, 82,
1448 132, 185, 235, 87, 137, 190, 240, 91, 141, 194,
1449 244, 61, 111, 164, 214, 65, 115, 168, 218, 70,
1450 120, 173, 223, 74, 124, 177, 227, 79, 129, 182,
1451 232, 83, 133, 186, 236, 88, 138, 191, 241, 92,
1452 142, 195, 245
1453};
1454
1455static pj_int16_t AMRWB_ordermap_1425[] =
1456{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001457 0, 4, 6, 101, 159, 220, 278, 7, 5, 3,
1458 47, 48, 49, 50, 51, 166, 167, 168, 169, 170,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001459 102, 160, 221, 279, 107, 165, 226, 284, 104, 162,
1460 223, 281, 105, 163, 224, 282, 108, 227, 106, 164,
1461 225, 283, 103, 161, 222, 280, 52, 2, 1, 109,
1462 228, 171, 19, 21, 12, 17, 18, 20, 16, 25,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001463 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001464 172, 31, 110, 229, 9, 33, 11, 111, 230, 54,
1465 173, 28, 27, 112, 231, 34, 35, 29, 46, 32,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001466 30, 55, 174, 37, 36, 39, 38, 40, 113, 232,
1467 41, 42, 43, 44, 45, 56, 114, 175, 233, 62,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001468 120, 181, 239, 75, 133, 194, 252, 57, 115, 176,
1469 234, 63, 121, 182, 240, 70, 128, 189, 247, 76,
1470 134, 195, 253, 83, 141, 202, 260, 92, 150, 211,
1471 269, 84, 142, 203, 261, 93, 151, 212, 270, 85,
1472 143, 204, 262, 94, 152, 213, 271, 86, 144, 205,
1473 263, 95, 153, 214, 272, 64, 122, 183, 241, 77,
1474 135, 196, 254, 65, 123, 184, 242, 78, 136, 197,
1475 255, 87, 145, 206, 264, 96, 154, 215, 273, 58,
1476 116, 177, 235, 66, 124, 185, 243, 71, 129, 190,
1477 248, 79, 137, 198, 256, 88, 146, 207, 265, 97,
1478 155, 216, 274, 59, 117, 178, 236, 67, 125, 186,
1479 244, 72, 130, 191, 249, 80, 138, 199, 257, 89,
1480 147, 208, 266, 98, 156, 217, 275, 60, 118, 179,
1481 237, 68, 126, 187, 245, 73, 131, 192, 250, 81,
1482 139, 200, 258, 90, 148, 209, 267, 99, 157, 218,
1483 276, 61, 119, 180, 238, 69, 127, 188, 246, 74,
1484 132, 193, 251, 82, 140, 201, 259, 91, 149, 210,
1485 268, 100, 158, 219, 277
1486};
1487
1488static pj_int16_t AMRWB_ordermap_1585[] =
1489{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001490 0, 4, 6, 109, 175, 244, 310, 7, 5, 3,
1491 47, 48, 49, 50, 51, 182, 183, 184, 185, 186,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001492 110, 176, 245, 311, 115, 181, 250, 316, 112, 178,
1493 247, 313, 113, 179, 248, 314, 116, 251, 114, 180,
1494 249, 315, 111, 177, 246, 312, 52, 2, 1, 117,
1495 252, 187, 19, 21, 12, 17, 18, 20, 16, 25,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001496 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001497 188, 31, 118, 253, 9, 33, 11, 119, 254, 54,
1498 189, 28, 27, 120, 255, 34, 35, 29, 46, 32,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001499 30, 55, 190, 37, 36, 39, 38, 40, 121, 256,
1500 41, 42, 43, 44, 45, 56, 122, 191, 257, 63,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001501 129, 198, 264, 76, 142, 211, 277, 89, 155, 224,
1502 290, 102, 168, 237, 303, 57, 123, 192, 258, 70,
1503 136, 205, 271, 83, 149, 218, 284, 96, 162, 231,
1504 297, 62, 128, 197, 263, 75, 141, 210, 276, 88,
1505 154, 223, 289, 101, 167, 236, 302, 58, 124, 193,
1506 259, 71, 137, 206, 272, 84, 150, 219, 285, 97,
1507 163, 232, 298, 59, 125, 194, 260, 64, 130, 199,
1508 265, 67, 133, 202, 268, 72, 138, 207, 273, 77,
1509 143, 212, 278, 80, 146, 215, 281, 85, 151, 220,
1510 286, 90, 156, 225, 291, 93, 159, 228, 294, 98,
1511 164, 233, 299, 103, 169, 238, 304, 106, 172, 241,
1512 307, 60, 126, 195, 261, 65, 131, 200, 266, 68,
1513 134, 203, 269, 73, 139, 208, 274, 78, 144, 213,
1514 279, 81, 147, 216, 282, 86, 152, 221, 287, 91,
1515 157, 226, 292, 94, 160, 229, 295, 99, 165, 234,
1516 300, 104, 170, 239, 305, 107, 173, 242, 308, 61,
1517 127, 196, 262, 66, 132, 201, 267, 69, 135, 204,
1518 270, 74, 140, 209, 275, 79, 145, 214, 280, 82,
1519 148, 217, 283, 87, 153, 222, 288, 92, 158, 227,
1520 293, 95, 161, 230, 296, 100, 166, 235, 301, 105,
1521 171, 240, 306, 108, 174, 243, 309
1522};
1523
1524static pj_int16_t AMRWB_ordermap_1825[] =
1525{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001526 0, 4, 6, 121, 199, 280, 358, 7, 5, 3,
1527 47, 48, 49, 50, 51, 206, 207, 208, 209, 210,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001528 122, 200, 281, 359, 127, 205, 286, 364, 124, 202,
1529 283, 361, 125, 203, 284, 362, 128, 287, 126, 204,
1530 285, 363, 123, 201, 282, 360, 52, 2, 1, 129,
1531 288, 211, 19, 21, 12, 17, 18, 20, 16, 25,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001532 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001533 212, 31, 130, 289, 9, 33, 11, 131, 290, 54,
1534 213, 28, 27, 132, 291, 34, 35, 29, 46, 32,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001535 30, 55, 214, 37, 36, 39, 38, 40, 133, 292,
1536 41, 42, 43, 44, 45, 56, 134, 215, 293, 198,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001537 299, 136, 120, 138, 60, 279, 58, 62, 357, 139,
1538 140, 295, 156, 57, 219, 297, 63, 217, 137, 170,
1539 300, 222, 64, 106, 61, 78, 294, 92, 142, 141,
1540 135, 221, 296, 301, 343, 59, 298, 184, 329, 315,
1541 220, 216, 265, 251, 218, 237, 352, 223, 157, 86,
1542 171, 87, 164, 351, 111, 302, 65, 178, 115, 323,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001543 72, 192, 101, 179, 93, 73, 193, 151, 337, 309,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001544 143, 274, 69, 324, 165, 150, 97, 338, 110, 310,
1545 330, 273, 68, 107, 175, 245, 114, 79, 113, 189,
1546 246, 259, 174, 71, 185, 96, 344, 100, 322, 83,
1547 334, 316, 333, 252, 161, 348, 147, 82, 269, 232,
1548 260, 308, 353, 347, 163, 231, 306, 320, 188, 270,
1549 146, 177, 266, 350, 256, 85, 149, 116, 191, 160,
1550 238, 258, 336, 305, 255, 88, 224, 99, 339, 230,
1551 228, 227, 272, 242, 241, 319, 233, 311, 102, 74,
1552 180, 275, 66, 194, 152, 325, 172, 247, 244, 261,
1553 117, 158, 166, 354, 75, 144, 108, 312, 94, 186,
1554 303, 80, 234, 89, 195, 112, 340, 181, 345, 317,
1555 326, 276, 239, 167, 118, 313, 70, 355, 327, 253,
1556 190, 176, 271, 104, 98, 153, 103, 90, 76, 267,
1557 277, 248, 225, 262, 182, 84, 154, 235, 335, 168,
1558 331, 196, 341, 249, 162, 307, 148, 349, 263, 321,
1559 257, 243, 229, 356, 159, 119, 67, 187, 173, 145,
1560 240, 77, 304, 332, 314, 342, 109, 254, 81, 278,
1561 105, 91, 346, 318, 183, 250, 197, 328, 95, 155,
1562 169, 268, 226, 236, 264
1563};
1564
1565static pj_int16_t AMRWB_ordermap_1985[] =
1566{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001567 0, 4, 6, 129, 215, 304, 390, 7, 5, 3,
1568 47, 48, 49, 50, 51, 222, 223, 224, 225, 226,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001569 130, 216, 305, 391, 135, 221, 310, 396, 132, 218,
1570 307, 393, 133, 219, 308, 394, 136, 311, 134, 220,
1571 309, 395, 131, 217, 306, 392, 52, 2, 1, 137,
1572 312, 227, 19, 21, 12, 17, 18, 20, 16, 25,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001573 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001574 228, 31, 138, 313, 9, 33, 11, 139, 314, 54,
1575 229, 28, 27, 140, 315, 34, 35, 29, 46, 32,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001576 30, 55, 230, 37, 36, 39, 38, 40, 141, 316,
1577 41, 42, 43, 44, 45, 56, 142, 231, 317, 63,
1578 73, 92, 340, 82, 324, 149, 353, 159, 334, 165,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001579 338, 178, 163, 254, 77, 168, 257, 153, 343, 57,
1580 248, 238, 79, 252, 166, 67, 80, 201, 101, 267,
1581 143, 164, 341, 255, 339, 187, 376, 318, 78, 328,
1582 362, 115, 232, 242, 253, 290, 276, 62, 58, 158,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001583 68, 93, 179, 319, 148, 169, 154, 72, 385, 329,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001584 333, 344, 102, 83, 144, 233, 323, 124, 243, 192,
1585 354, 237, 64, 247, 202, 209, 150, 116, 335, 268,
1586 239, 299, 188, 196, 298, 94, 195, 258, 123, 363,
1587 384, 109, 325, 371, 170, 370, 84, 110, 295, 180,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001588 74, 210, 191, 106, 291, 205, 367, 381, 377, 206,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001589 355, 122, 119, 120, 383, 160, 105, 108, 277, 380,
1590 294, 284, 285, 345, 208, 269, 249, 366, 386, 300,
1591 297, 259, 125, 369, 197, 97, 194, 286, 211, 281,
1592 280, 183, 372, 87, 155, 283, 59, 348, 327, 184,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001593 76, 111, 330, 203, 349, 69, 98, 152, 145, 189,
1594 66, 320, 337, 173, 358, 251, 198, 174, 263, 262,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001595 126, 241, 193, 88, 388, 117, 95, 387, 112, 359,
1596 287, 244, 103, 272, 301, 171, 162, 234, 273, 127,
1597 373, 181, 292, 85, 378, 302, 121, 107, 364, 346,
1598 356, 212, 278, 213, 65, 382, 288, 207, 113, 175,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001599 99, 296, 374, 368, 199, 260, 185, 336, 331, 161,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001600 270, 264, 250, 240, 75, 350, 151, 60, 89, 321,
1601 156, 274, 360, 326, 70, 282, 167, 146, 352, 81,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001602 91, 389, 266, 245, 177, 235, 190, 256, 204, 342,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001603 128, 118, 303, 104, 379, 182, 114, 375, 200, 96,
1604 293, 172, 214, 365, 279, 86, 289, 351, 347, 357,
1605 261, 186, 176, 271, 90, 100, 147, 322, 275, 361,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001606 71, 332, 61, 265, 157, 246, 236
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001607};
1608
1609static pj_int16_t AMRWB_ordermap_2305[] =
1610{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001611 0, 4, 6, 145, 247, 352, 454, 7, 5, 3,
1612 47, 48, 49, 50, 51, 254, 255, 256, 257, 258,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001613 146, 248, 353, 455, 151, 253, 358, 460, 148, 250,
1614 355, 457, 149, 251, 356, 458, 152, 359, 150, 252,
1615 357, 459, 147, 249, 354, 456, 52, 2, 1, 153,
1616 360, 259, 19, 21, 12, 17, 18, 20, 16, 25,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001617 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001618 260, 31, 154, 361, 9, 33, 11, 155, 362, 54,
1619 261, 28, 27, 156, 363, 34, 35, 29, 46, 32,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001620 30, 55, 262, 37, 36, 39, 38, 40, 157, 364,
1621 41, 42, 43, 44, 45, 56, 158, 263, 365, 181,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001622 192, 170, 79, 57, 399, 90, 159, 297, 377, 366,
1623 275, 68, 183, 388, 286, 194, 299, 92, 70, 182,
1624 401, 172, 59, 91, 58, 400, 368, 161, 81, 160,
1625 264, 171, 80, 389, 390, 378, 379, 193, 298, 69,
1626 266, 265, 367, 277, 288, 276, 287, 184, 60, 195,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001627 82, 93, 71, 369, 402, 173, 162, 444, 300, 391,
1628 98, 76, 278, 61, 267, 374, 135, 411, 167, 102,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001629 380, 200, 87, 178, 65, 94, 204, 124, 72, 342,
1630 189, 305, 381, 396, 433, 301, 226, 407, 289, 237,
1631 113, 215, 185, 128, 309, 403, 116, 320, 196, 331,
1632 370, 422, 174, 64, 392, 83, 425, 219, 134, 188,
1633 432, 112, 427, 139, 279, 163, 436, 208, 447, 218,
1634 236, 229, 97, 294, 385, 230, 166, 268, 177, 443,
1635 225, 426, 101, 272, 138, 127, 290, 117, 347, 199,
1636 414, 95, 140, 240, 410, 395, 209, 129, 283, 346,
1637 105, 241, 437, 86, 308, 448, 203, 345, 186, 107,
1638 220, 415, 334, 319, 106, 313, 118, 123, 73, 207,
1639 421, 214, 384, 373, 438, 62, 371, 341, 75, 449,
1640 168, 323, 164, 242, 416, 324, 304, 197, 335, 404,
1641 271, 63, 191, 325, 96, 169, 231, 280, 312, 187,
1642 406, 84, 201, 100, 67, 382, 175, 336, 202, 330,
1643 269, 393, 376, 383, 293, 307, 409, 179, 285, 314,
1644 302, 372, 398, 190, 180, 89, 99, 103, 232, 78,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001645 88, 77, 136, 387, 165, 198, 394, 125, 176, 428,
1646 74, 375, 238, 227, 66, 273, 282, 141, 306, 412,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001647 114, 85, 130, 348, 119, 291, 296, 386, 233, 397,
1648 303, 405, 284, 445, 423, 221, 210, 205, 450, 108,
1649 274, 434, 216, 343, 337, 142, 243, 321, 408, 451,
1650 310, 292, 120, 109, 281, 439, 270, 429, 332, 295,
1651 418, 211, 315, 222, 326, 131, 430, 244, 327, 349,
1652 417, 316, 143, 338, 440, 234, 110, 212, 452, 245,
1653 121, 419, 350, 223, 132, 441, 328, 413, 317, 339,
1654 126, 104, 137, 446, 344, 239, 435, 115, 333, 206,
1655 322, 217, 228, 424, 453, 311, 351, 111, 442, 224,
1656 213, 122, 431, 340, 235, 246, 133, 144, 420, 329,
1657 318
1658};
1659
1660static pj_int16_t AMRWB_ordermap_2385[] =
1661{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001662 0, 4, 6, 145, 251, 360, 466, 7, 5, 3,
1663 47, 48, 49, 50, 51, 262, 263, 264, 265, 266,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001664 146, 252, 361, 467, 151, 257, 366, 472, 148, 254,
1665 363, 469, 149, 255, 364, 470, 156, 371, 150, 256,
1666 365, 471, 147, 253, 362, 468, 52, 2, 1, 157,
1667 372, 267, 19, 21, 12, 17, 18, 20, 16, 25,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001668 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001669 268, 31, 152, 153, 154, 155, 258, 259, 260, 261,
1670 367, 368, 369, 370, 473, 474, 475, 476, 158, 373,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001671 9, 33, 11, 159, 374, 54, 269, 28, 27, 160,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001672 375, 34, 35, 29, 46, 32, 30, 55, 270, 37,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001673 36, 39, 38, 40, 161, 376, 41, 42, 43, 44,
1674 45, 56, 162, 271, 377, 185, 196, 174, 79, 57,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001675 411, 90, 163, 305, 389, 378, 283, 68, 187, 400,
1676 294, 198, 307, 92, 70, 186, 413, 176, 59, 91,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001677 58, 412, 380, 165, 81, 164, 272, 175, 80, 401,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001678 402, 390, 391, 197, 306, 69, 274, 273, 379, 285,
1679 296, 284, 295, 188, 60, 199, 82, 93, 71, 381,
1680 414, 177, 166, 456, 308, 403, 98, 76, 286, 61,
1681 275, 386, 135, 423, 171, 102, 392, 204, 87, 182,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001682 65, 94, 208, 124, 72, 350, 193, 313, 393, 408,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001683 445, 309, 230, 419, 297, 241, 113, 219, 189, 128,
1684 317, 415, 116, 328, 200, 339, 382, 434, 178, 64,
1685 404, 83, 437, 223, 134, 192, 444, 112, 439, 139,
1686 287, 167, 448, 212, 459, 222, 240, 233, 97, 302,
1687 397, 234, 170, 276, 181, 455, 229, 438, 101, 280,
1688 138, 127, 298, 117, 355, 203, 426, 95, 140, 244,
1689 422, 407, 213, 129, 291, 354, 105, 245, 449, 86,
1690 316, 460, 207, 353, 190, 107, 224, 427, 342, 327,
1691 106, 321, 118, 123, 73, 211, 433, 218, 396, 385,
1692 450, 62, 383, 349, 75, 461, 172, 331, 168, 246,
1693 428, 332, 312, 201, 343, 416, 279, 63, 195, 333,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001694 96, 173, 235, 288, 320, 191, 418, 84, 205, 100,
1695 67, 394, 179, 344, 206, 338, 277, 405, 388, 395,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001696 301, 315, 421, 183, 293, 322, 310, 384, 410, 194,
1697 184, 89, 99, 103, 236, 78, 88, 77, 136, 399,
1698 169, 202, 406, 125, 180, 440, 74, 387, 242, 231,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001699 66, 281, 290, 141, 314, 424, 114, 85, 130, 356,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001700 119, 299, 304, 398, 237, 409, 311, 417, 292, 457,
1701 435, 225, 214, 209, 462, 108, 282, 446, 220, 351,
1702 345, 142, 247, 329, 420, 463, 318, 300, 120, 109,
1703 289, 451, 278, 441, 340, 303, 430, 215, 323, 226,
1704 334, 131, 442, 248, 335, 357, 429, 324, 143, 346,
1705 452, 238, 110, 216, 464, 249, 121, 431, 358, 227,
1706 132, 453, 336, 425, 325, 347, 126, 104, 137, 458,
1707 352, 243, 447, 115, 341, 210, 330, 221, 232, 436,
1708 465, 319, 359, 111, 454, 228, 217, 122, 443, 348,
1709 239, 250, 133, 144, 432, 337, 326
1710};
1711
1712static pj_int16_t *AMRWB_ordermaps[9] =
1713{
1714 AMRWB_ordermap_660,
1715 AMRWB_ordermap_885,
1716 AMRWB_ordermap_1265,
1717 AMRWB_ordermap_1425,
1718 AMRWB_ordermap_1585,
1719 AMRWB_ordermap_1825,
1720 AMRWB_ordermap_1985,
1721 AMRWB_ordermap_2305,
1722 AMRWB_ordermap_2385
1723};
1724
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001725static pj_uint8_t AMRNB_framelen[16] =
1726 {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 5};
1727static pj_uint16_t AMRNB_framelenbits[9] =
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001728 {95, 103, 118, 134, 148, 159, 204, 244, 39};
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001729static pj_uint16_t AMRNB_bitrates[8] =
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001730 {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200};
1731
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001732static pj_uint8_t AMRWB_framelen[16] =
1733 {17, 23, 32, 37, 40, 46, 50, 58, 60, 5, 0, 0, 0, 0, 0, 5};
1734static pj_uint16_t AMRWB_framelenbits[10] =
1735 {132, 177, 253, 285, 317, 365, 397, 461, 477, 40};
1736static pj_uint16_t AMRWB_bitrates[9] =
1737 {6600, 8850, 12650, 14250, 15850, 18250, 19850, 23050, 23850};
1738
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001739
1740/* Get mode based on bitrate */
1741static int amr_get_mode(unsigned bitrate)
1742{
1743 int mode = -1;
1744
1745 if(bitrate==4750){
1746 mode = 0;
1747 } else if(bitrate==5150){
1748 mode = 1;
1749 } else if(bitrate==5900){
1750 mode = 2;
1751 } else if(bitrate==6700){
1752 mode = 3;
1753 } else if(bitrate==7400){
1754 mode = 4;
1755 } else if(bitrate==7950){
1756 mode = 5;
1757 } else if(bitrate==10200){
1758 mode = 6;
1759 } else if(bitrate==12200){
1760 mode = 7;
1761
1762 /* AMRWB */
1763 } else if(bitrate==6600){
1764 mode = 0;
1765 } else if(bitrate==8850){
1766 mode = 1;
1767 } else if(bitrate==12650){
1768 mode = 2;
1769 } else if(bitrate==14250){
1770 mode = 3;
1771 } else if(bitrate==15850){
1772 mode = 4;
1773 } else if(bitrate==18250){
1774 mode = 5;
1775 } else if(bitrate==19850){
1776 mode = 6;
1777 } else if(bitrate==23050){
1778 mode = 7;
1779 } else if(bitrate==23850){
1780 mode = 8;
1781 }
1782 return mode;
1783}
1784
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001785/* Rearrange AMR bitstream of rtp_frame:
1786 * - make the start_bit to be 0
1787 * - if it is speech frame, reorder bitstream from sensitivity bits order
1788 * to encoder bits order.
1789 */
1790static void predecode_amr( ipp_private_t *codec_data,
1791 const pjmedia_frame *rtp_frame,
1792 USC_Bitstream *usc_frame)
1793{
1794 pj_uint8_t FT, Q;
1795 pj_int8_t amr_bits[477 + 7] = {0};
1796 pj_int8_t *p_amr_bits = &amr_bits[0];
1797 unsigned i;
1798 /* read cursor */
1799 pj_uint8_t *r = (pj_uint8_t*)rtp_frame->buf;
1800 pj_uint8_t start_bit;
1801 /* write cursor */
1802 pj_uint8_t *w = (pj_uint8_t*)rtp_frame->buf;
1803 /* env vars for AMR or AMRWB */
1804 pj_bool_t AMRWB;
1805 pj_uint8_t SID_FT = 8;
1806 pj_uint8_t *framelen_tbl = AMRNB_framelen;
1807 pj_uint16_t *framelenbit_tbl = AMRNB_framelenbits;
1808 pj_uint16_t *bitrate_tbl = AMRNB_bitrates;
1809 pj_int16_t **order_map = AMRNB_ordermaps;
1810
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001811 AMRWB = (ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMRWB);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001812 if (AMRWB) {
1813 SID_FT = 9;
1814 framelen_tbl = AMRWB_framelen;
1815 framelenbit_tbl = AMRWB_framelenbits;
1816 bitrate_tbl = AMRWB_bitrates;
1817 order_map = AMRWB_ordermaps;
1818 }
1819
1820 start_bit = (pj_uint8_t)((rtp_frame->bit_info & 0x0700) >> 8);
1821 FT = (pj_uint8_t)(rtp_frame->bit_info & 0x0F);
1822 Q = (pj_uint8_t)((rtp_frame->bit_info >> 16) & 0x01);
1823
1824 /* unpack AMR bitstream if there is any data */
1825 if (FT <= SID_FT) {
1826 i = 0;
1827 if (start_bit) {
1828 for (; i < (unsigned)(8-start_bit); ++i)
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001829 *p_amr_bits++ = (pj_uint8_t)((*r >> (7-start_bit-i)) & 1);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001830 ++r;
1831 }
1832 for(; i < framelenbit_tbl[FT]; i += 8) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001833 *p_amr_bits++ = (pj_uint8_t)((*r >> 7) & 1);
1834 *p_amr_bits++ = (pj_uint8_t)((*r >> 6) & 1);
1835 *p_amr_bits++ = (pj_uint8_t)((*r >> 5) & 1);
1836 *p_amr_bits++ = (pj_uint8_t)((*r >> 4) & 1);
1837 *p_amr_bits++ = (pj_uint8_t)((*r >> 3) & 1);
1838 *p_amr_bits++ = (pj_uint8_t)((*r >> 2) & 1);
1839 *p_amr_bits++ = (pj_uint8_t)((*r >> 1) & 1);
1840 *p_amr_bits++ = (pj_uint8_t)((*r ) & 1);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001841 ++r;
1842 }
1843 }
1844
1845 if (FT < SID_FT) {
1846 /* Speech */
1847 pj_int16_t *order_map_;
1848
1849 order_map_ = order_map[FT];
1850 pj_bzero(rtp_frame->buf, rtp_frame->size);
1851 for(i = 0; i < framelenbit_tbl[FT]; ++i) {
1852 if (amr_bits[i]) {
1853 pj_uint16_t bitpos;
1854 bitpos = order_map_[i];
1855 w[bitpos>>3] |= 1 << (7 - (bitpos % 8));
1856 }
1857 }
1858 usc_frame->nbytes = framelen_tbl[FT];
1859 if (Q)
1860 usc_frame->frametype = 0;
1861 else
1862 usc_frame->frametype = AMRWB ? 6 : 5;
1863 usc_frame->bitrate = bitrate_tbl[FT];
1864 } else if (FT == SID_FT) {
1865 /* SID */
1866 pj_uint8_t w_bitptr = 0;
1867 pj_uint8_t STI;
1868 pj_uint8_t FT_;
1869
1870 STI = amr_bits[35];
1871 if (AMRWB)
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001872 FT_ = (pj_uint8_t)((amr_bits[36] << 3) | (amr_bits[37] << 2) |
1873 (amr_bits[38] << 1) | amr_bits[39]);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001874 else
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001875 FT_ = (pj_uint8_t)((amr_bits[36] << 2) | (amr_bits[37] << 1) |
1876 amr_bits[38]);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001877
1878 pj_bzero(rtp_frame->buf, rtp_frame->size);
1879 for(i = 0; i < framelenbit_tbl[FT]; ++i) {
1880 if (amr_bits[i])
1881 *w |= (1 << (7-w_bitptr));
1882
1883 if (++w_bitptr == 8) {
1884 ++w;
1885 w_bitptr = 0;
1886 }
1887 }
1888
1889 usc_frame->nbytes = 5;
1890 if (Q)
1891 usc_frame->frametype = STI? 2 : 1;
1892 else
1893 usc_frame->frametype = AMRWB ? 7 : 6;
1894
1895 usc_frame->bitrate = bitrate_tbl[FT_];
1896 } else {
1897 /* NO DATA */
1898 usc_frame->nbytes = 0;
1899 usc_frame->frametype = 3;
1900 usc_frame->bitrate = 0;
1901 }
1902
1903 usc_frame->pBuffer = rtp_frame->buf;
1904}
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001905
1906static pj_status_t pack_amr(ipp_private_t *codec_data, void *pkt,
1907 pj_size_t *pkt_size, pj_size_t max_pkt_size)
1908{
1909 /* Settings */
1910 pj_uint8_t CMR = 15; /* We don't request any code mode */
1911 pj_uint8_t octet_aligned = 0; /* default==0 when SDP not specifying */
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001912 /* Write cursor */
1913 pj_uint8_t *w = (pj_uint8_t*)pkt;
1914 pj_uint8_t w_bitptr = 0;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001915 /* Read cursor */
1916 pj_uint8_t *r;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001917 /* env vars for AMR or AMRWB */
1918 pj_bool_t AMRWB;
1919 pj_uint8_t SID_FT = 8;
1920 pj_uint8_t *framelen_tbl = AMRNB_framelen;
1921 pj_uint16_t *framelenbit_tbl = AMRNB_framelenbits;
1922 pj_uint16_t *bitrate_tbl = AMRNB_bitrates;
1923 pj_int16_t **order_map = AMRNB_ordermaps;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001924
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001925 AMRWB = ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMRWB;
1926 if (AMRWB) {
1927 SID_FT = 9;
1928 framelen_tbl = AMRWB_framelen;
1929 framelenbit_tbl = AMRWB_framelenbits;
1930 bitrate_tbl = AMRWB_bitrates;
1931 order_map = AMRWB_ordermaps;
1932 }
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001933
1934 PJ_TODO(Make_sure_buffer_is_enough_for_packing_AMR_packet);
1935
1936 r = (pj_uint8_t*)pkt + max_pkt_size - *pkt_size;
1937
1938 /* Align pkt buf right */
1939 pj_memmove(r, w, *pkt_size);
1940
1941 /* Code Mode Request, 4 bits */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001942 *w = (pj_uint8_t)(CMR << 4);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001943 w_bitptr = 4;
1944 if (octet_aligned) {
1945 ++w;
1946 w_bitptr = 0;
1947 }
1948
1949 /* Table Of Contents, 6 bits each */
1950 for (;;) {
1951 pj_uint8_t TOC;
1952 pj_uint8_t F, FT, Q;
1953
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001954 F = (pj_uint8_t)((*r & 0x40) == 0);
1955 FT = (pj_uint8_t)(*r & 0x0F);
1956 Q = (pj_uint8_t)((*r & 0x80) == 0);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001957
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001958 pj_assert(FT <= SID_FT || FT == 14 || FT == 15);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001959 TOC = (pj_uint8_t)((F<<5) | (FT<<1) | Q);
1960
1961 if (w_bitptr == 0) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001962 *w = (pj_uint8_t)(TOC<<2);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001963 w_bitptr = 6;
1964 } else if (w_bitptr == 2) {
1965 *w++ |= TOC;
1966 w_bitptr = 0;
1967 } else if (w_bitptr == 4) {
1968 *w++ |= TOC>>2;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001969 *w = (pj_uint8_t)(TOC<<6);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001970 w_bitptr = 2;
1971 } else if (w_bitptr == 6) {
1972 *w++ |= TOC>>4;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001973 *w = (pj_uint8_t)(TOC<<4);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001974 w_bitptr = 4;
1975 }
1976
1977 if (octet_aligned) {
1978 ++w;
1979 w_bitptr = 0;
1980 }
1981
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001982 if (FT > SID_FT)
1983 /* NO DATA */
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001984 r += 1;
1985 else
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001986 r += framelen_tbl[FT] + 1;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001987
1988 /* Last frame */
1989 if (!F)
1990 break;
1991 }
1992
1993 /* Speech frames */
1994 r = (pj_uint8_t*)pkt + max_pkt_size - *pkt_size;
1995
1996 for (;;) {
1997 pj_uint8_t F, FT;
1998 pj_int8_t amr_bits[477 + 7] = {0};
1999 pj_int8_t *p_amr_bits = &amr_bits[0];
2000 unsigned i;
2001
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002002 F = (pj_uint8_t)((*r & 0x40) == 0);
2003 FT = (pj_uint8_t)(*r & 0x0F);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002004 pj_assert(FT <= SID_FT || FT == 14 || FT == 15);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002005
2006 ++r;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002007 if (FT > SID_FT) {
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002008 if (!F)
2009 break;
2010 continue;
2011 }
2012
2013 /* Unpack bits */
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002014 for(i = 0; i < framelen_tbl[FT]; ++i) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002015 *p_amr_bits++ = (pj_uint8_t)((*r >> 7) & 1);
2016 *p_amr_bits++ = (pj_uint8_t)((*r >> 6) & 1);
2017 *p_amr_bits++ = (pj_uint8_t)((*r >> 5) & 1);
2018 *p_amr_bits++ = (pj_uint8_t)((*r >> 4) & 1);
2019 *p_amr_bits++ = (pj_uint8_t)((*r >> 3) & 1);
2020 *p_amr_bits++ = (pj_uint8_t)((*r >> 2) & 1);
2021 *p_amr_bits++ = (pj_uint8_t)((*r >> 1) & 1);
2022 *p_amr_bits++ = (pj_uint8_t)((*r ) & 1);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002023 ++r;
2024 }
2025
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002026 if (FT < SID_FT) {
2027 /* Speech */
2028 pj_int16_t *order_map_;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002029
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002030 /* Put bits in the packet, sensitivity descending ordered */
2031 order_map_ = order_map[FT];
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002032 if (w_bitptr == 0) *w = 0;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002033 for(i = 0; i < framelenbit_tbl[FT]; ++i) {
2034 pj_uint8_t bit;
2035 bit = amr_bits[order_map_[i]];
2036
2037 if (bit)
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002038 *w |= (1 << (7-w_bitptr));
2039
2040 if (++w_bitptr == 8) {
2041 w_bitptr = 0;
2042 ++w;
2043 *w = 0;
2044 }
2045 }
2046
2047 if (octet_aligned) {
2048 ++w;
2049 w_bitptr = 0;
2050 }
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002051 } else if (FT == SID_FT) {
2052 /* SID */
2053 pj_uint8_t STI = 0;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002054
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002055 amr_bits[35] = (pj_uint8_t)(STI & 1);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002056
2057 if (AMRWB) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002058 amr_bits[36] = (pj_uint8_t)((FT >> 3) & 1);
2059 amr_bits[37] = (pj_uint8_t)((FT >> 2) & 1);
2060 amr_bits[38] = (pj_uint8_t)((FT >> 1) & 1);
2061 amr_bits[39] = (pj_uint8_t)((FT) & 1);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002062 } else {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002063 amr_bits[36] = (pj_uint8_t)((FT >> 2) & 1);
2064 amr_bits[37] = (pj_uint8_t)((FT >> 1) & 1);
2065 amr_bits[38] = (pj_uint8_t)((FT) & 1);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002066 }
2067
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002068 if (w_bitptr == 0) *w = 0;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002069 for(i = 0; i < framelenbit_tbl[FT]; ++i) {
2070 if (amr_bits[i])
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002071 *w |= (1 << (7-w_bitptr));
2072
2073 if (++w_bitptr == 8) {
2074 w_bitptr = 0;
2075 ++w;
2076 *w = 0;
2077 }
2078 }
2079
2080 if (octet_aligned) {
2081 ++w;
2082 w_bitptr = 0;
2083 }
2084 }
2085
2086 if (!F)
2087 break;
2088 }
2089
2090 *pkt_size = w - (pj_uint8_t*)pkt;
2091 if (w_bitptr)
2092 *pkt_size += 1;
2093
2094 pj_assert(*pkt_size <= max_pkt_size);
2095
2096 return PJ_SUCCESS;
2097}
2098
2099
2100/* Parse AMR payload into frames. Frame.bit_info will contain start_bit and
2101 * AMR frame type, it is mapped as below (bit 0:MSB - bit 31:LSB)
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002102 * - bit 0-16: degraded quality flag (Q)
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002103 * - bit 17-24: start_bit
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002104 * - bit 25-32: frame_type (FT)
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002105 */
2106static pj_status_t parse_amr(ipp_private_t *codec_data, void *pkt,
2107 pj_size_t pkt_size, const pj_timestamp *ts,
2108 unsigned *frame_cnt, pjmedia_frame frames[])
2109{
2110 unsigned cnt = 0;
2111 pj_timestamp ts_ = *ts;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002112 /* Settings */
2113 pj_uint8_t CMR = 15; /* See if remote request code mode */
2114 pj_uint8_t octet_aligned = 0; /* default==0 when SDP not specifying */
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002115 /* Read cursor */
2116 pj_uint8_t r_bitptr = 0;
2117 pj_uint8_t *r = (pj_uint8_t*)pkt;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002118 /* env vars for AMR or AMRWB */
2119 pj_bool_t AMRWB;
2120 pj_uint8_t SID_FT = 8;
2121 pj_uint8_t *framelen_tbl = AMRNB_framelen;
2122 pj_uint16_t *framelenbit_tbl = AMRNB_framelenbits;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002123
2124 PJ_UNUSED_ARG(pkt_size);
2125
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002126 AMRWB = ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMRWB;
2127 if (AMRWB) {
2128 SID_FT = 9;
2129 framelen_tbl = AMRWB_framelen;
2130 framelenbit_tbl = AMRWB_framelenbits;
2131 }
2132
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002133 *frame_cnt = 0;
2134
2135 /* Code Mode Request, 4 bits */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002136 CMR = (pj_uint8_t)((*r >> 4) & 0x0F);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002137 r_bitptr = 4;
2138 if (octet_aligned) {
2139 ++r;
2140 r_bitptr = 0;
2141 }
2142
2143 /* Table Of Contents, 6 bits each */
2144 for (;;) {
2145 pj_uint8_t TOC = 0;
2146 pj_uint8_t F, FT, Q;
2147
2148 if (r_bitptr == 0) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002149 TOC = (pj_uint8_t)(*r >> 2);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002150 r_bitptr = 6;
2151 } else if (r_bitptr == 2) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002152 TOC = (pj_uint8_t)(*r++ & 0x3F);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002153 r_bitptr = 0;
2154 } else if (r_bitptr == 4) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002155 TOC = (pj_uint8_t)((*r++ & 0x0f) << 2);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002156 TOC |= *r >> 6;
2157 r_bitptr = 2;
2158 } else if (r_bitptr == 6) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002159 TOC = (pj_uint8_t)((*r++ & 0x03) << 4);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002160 TOC |= *r >> 4;
2161 r_bitptr = 4;
2162 }
2163
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002164 F = (pj_uint8_t)(TOC >> 5);
2165 FT = (pj_uint8_t)((TOC >> 1) & 0x0F);
2166 Q = (pj_uint8_t)(TOC & 1);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002167
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002168 if (FT > SID_FT && FT < 14) {
2169 pj_assert(!"Invalid AMR frametype, stream may be corrupted!");
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002170 break;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002171 }
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002172
2173 if (octet_aligned) {
2174 ++r;
2175 r_bitptr = 0;
2176 }
2177
2178 /* Set frame attributes */
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002179 frames[cnt].bit_info = FT | (Q << 16);
2180 frames[cnt].timestamp = ts_;
2181 frames[cnt].type = PJMEDIA_FRAME_TYPE_AUDIO;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002182
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002183 ts_.u64 += ipp_codec[codec_data->codec_idx].samples_per_frame;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002184 ++cnt;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002185
2186 if (!F || cnt == *frame_cnt)
2187 break;
2188 }
2189 *frame_cnt = cnt;
2190
2191 cnt = 0;
2192
2193 /* Speech frames */
2194 while (cnt < *frame_cnt) {
2195 unsigned FT;
2196
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002197 FT = frames[cnt].bit_info & 0x0F;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002198
2199 frames[cnt].bit_info |= (r_bitptr << 8);
2200 frames[cnt].buf = r;
2201
2202 if (octet_aligned) {
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002203 r += framelen_tbl[FT];
2204 frames[cnt].size = framelen_tbl[FT];
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002205 } else {
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002206 if (FT == 14 || FT == 15) {
2207 /* NO DATA */
2208 frames[cnt].size = 0;
2209 } else {
2210 unsigned adv_bit;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002211
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002212 adv_bit = framelenbit_tbl[FT] + r_bitptr;
2213 r += adv_bit >> 3;
2214 r_bitptr = (pj_uint8_t)(adv_bit % 8);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002215
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002216 frames[cnt].size = adv_bit >> 3;
2217 if (r_bitptr)
2218 ++frames[cnt].size;
2219 }
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002220 }
2221 ++cnt;
2222 }
2223
2224 return PJ_SUCCESS;
2225}
2226
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002227#endif /* PJMEDIA_HAS_INTEL_IPP_CODEC_AMR */
2228
2229
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002230#if defined(_MSC_VER) && PJMEDIA_AUTO_LINK_IPP_LIBS
2231# pragma comment( lib, "ippcore.lib")
2232# pragma comment( lib, "ipps.lib")
2233# pragma comment( lib, "ippsc.lib")
2234# pragma comment( lib, "ippsr.lib")
2235# pragma comment( lib, "usc.lib")
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002236#endif
2237
2238
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002239#endif /* PJMEDIA_HAS_INTEL_IPP */
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002240