blob: 302811b277cea1f4770b23ba4d0cd2ea0de6b89f [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
Nanang Izzuddine3a6fca2008-08-27 13:15:25 +0000968 if (pt == PJMEDIA_RTP_PT_G729) {
969 if (out.frametype == 1) {
970 /* SID */
971 break;
972 } else if (out.frametype == 0) {
973 /* Untransmitted */
974 tx -= out.nbytes;
975 break;
976 }
Nanang Izzuddin23a00b72008-08-25 13:58:25 +0000977 }
978#endif
979
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000980 }
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000981
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +0000982 if (ippc->pack != NULL) {
983 ippc->pack(codec_data, output->buf, &tx, output_buf_len);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +0000984 }
985
986 /* Check if we don't need to transmit the frame (DTX) */
987 if (tx == 0) {
988 output->buf = NULL;
989 output->size = 0;
990 output->timestamp.u64 = input->timestamp.u64;
991 output->type = PJMEDIA_FRAME_TYPE_NONE;
992 return PJ_SUCCESS;
993 }
994
995 output->size = tx;
996 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
997 output->timestamp = input->timestamp;
998
999 return PJ_SUCCESS;
1000}
1001
1002/*
1003 * Decode frame.
1004 */
1005static pj_status_t ipp_codec_decode( pjmedia_codec *codec,
1006 const struct pjmedia_frame *input,
1007 unsigned output_buf_len,
1008 struct pjmedia_frame *output)
1009{
1010 ipp_private_t *codec_data = (ipp_private_t*) codec->codec_data;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001011 struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001012 unsigned samples_per_frame;
1013 USC_PCMStream out;
1014 USC_Bitstream in;
1015 pj_uint8_t pt;
1016
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001017 pt = ippc->pt;
1018 samples_per_frame = ippc->samples_per_frame;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001019
1020 PJ_ASSERT_RETURN(output_buf_len >= samples_per_frame << 1,
1021 PJMEDIA_CODEC_EPCMTOOSHORT);
1022
1023 if (input->type == PJMEDIA_FRAME_TYPE_AUDIO) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001024 if (ippc->predecode) {
1025 ippc->predecode(codec_data, input, &in);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001026 } else {
1027 /* Most IPP codecs have frametype==0 for speech frame */
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001028 in.pBuffer = (char*)input->buf;
1029 in.nbytes = input->size;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001030 in.frametype = 0;
1031 in.bitrate = codec_data->info->params.modes.bitrate;
1032 }
1033
1034 out.pBuffer = output->buf;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001035 }
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001036
1037 if (input->type != PJMEDIA_FRAME_TYPE_AUDIO ||
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001038 USC_NoError != ippc->fxns->Decode(codec_data->dec, &in, &out))
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001039 {
1040 pjmedia_zero_samples((pj_int16_t*)output->buf, samples_per_frame);
1041 output->size = samples_per_frame << 1;
1042 output->timestamp.u64 = input->timestamp.u64;
1043 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
1044 return PJ_SUCCESS;
1045 }
1046
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001047#if PJMEDIA_HAS_INTEL_IPP_CODEC_G726
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001048 /* For G.726: amplify decoding result (USC G.726 encoder deamplified it) */
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001049 if (pt == PJMEDIA_RTP_PT_G726_16 || pt == PJMEDIA_RTP_PT_G726_24 ||
1050 pt == PJMEDIA_RTP_PT_G726_32 || pt == PJMEDIA_RTP_PT_G726_40)
1051 {
1052 unsigned i;
1053 pj_int16_t *s = (pj_int16_t*)output->buf;
1054
1055 for (i = 0; i < samples_per_frame; ++i)
1056 s[i] <<= 2;
1057 }
1058#endif
1059
1060 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
1061 output->size = samples_per_frame << 1;
1062 output->timestamp.u64 = input->timestamp.u64;
1063
1064 /* Invoke external PLC if codec has no internal PLC */
1065 if (codec_data->plc && codec_data->plc_enabled)
1066 pjmedia_plc_save(codec_data->plc, (pj_int16_t*)output->buf);
1067
1068 return PJ_SUCCESS;
1069}
1070
1071/*
1072 * Recover lost frame.
1073 */
1074static pj_status_t ipp_codec_recover(pjmedia_codec *codec,
1075 unsigned output_buf_len,
1076 struct pjmedia_frame *output)
1077{
1078 ipp_private_t *codec_data = (ipp_private_t*) codec->codec_data;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001079 struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001080 unsigned samples_per_frame;
1081
1082 PJ_UNUSED_ARG(output_buf_len);
1083
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001084 samples_per_frame = ippc->samples_per_frame;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001085
1086 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
1087 output->size = samples_per_frame << 1;
1088
1089 if (codec_data->plc_enabled) {
1090 if (codec_data->plc) {
1091 pjmedia_plc_generate(codec_data->plc, (pj_int16_t*)output->buf);
1092 } else {
1093 USC_PCMStream out;
1094 out.pBuffer = output->buf;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001095 ippc->fxns->Decode(codec_data->dec, NULL, &out);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001096 }
1097 } else {
1098 pjmedia_zero_samples((pj_int16_t*)output->buf, samples_per_frame);
1099 }
1100
1101 return PJ_SUCCESS;
1102}
1103
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001104#if PJMEDIA_HAS_INTEL_IPP_CODEC_G729
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001105
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001106static void predecode_g729( ipp_private_t *codec_data,
1107 const pjmedia_frame *rtp_frame,
1108 USC_Bitstream *usc_frame)
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001109{
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001110 switch (rtp_frame->size) {
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001111 case 2:
1112 /* SID */
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001113 usc_frame->frametype = 1;
1114 usc_frame->bitrate = codec_data->info->params.modes.bitrate;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001115 break;
1116 case 8:
1117 /* G729D */
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001118 usc_frame->frametype = 2;
1119 usc_frame->bitrate = 6400;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001120 break;
1121 case 10:
1122 /* G729 */
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001123 usc_frame->frametype = 3;
1124 usc_frame->bitrate = 8000;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001125 break;
1126 case 15:
1127 /* G729E */
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001128 usc_frame->frametype = 4;
1129 usc_frame->bitrate = 11800;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001130 break;
1131 default:
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001132 usc_frame->frametype = 0;
1133 usc_frame->bitrate = 0;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001134 break;
1135 }
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001136
1137 usc_frame->pBuffer = rtp_frame->buf;
1138 usc_frame->nbytes = rtp_frame->size;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001139}
1140
1141#endif /* PJMEDIA_HAS_INTEL_IPP_CODEC_G729 */
1142
1143
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001144#if PJMEDIA_HAS_INTEL_IPP_CODEC_G723_1
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001145
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001146static void predecode_g723( ipp_private_t *codec_data,
1147 const pjmedia_frame *rtp_frame,
1148 USC_Bitstream *usc_frame)
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001149{
1150 int i, HDR = 0;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001151 pj_uint8_t *f = (pj_uint8_t*)rtp_frame->buf;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001152
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001153 PJ_UNUSED_ARG(codec_data);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001154
1155 for (i = 0; i < 2; ++i){
1156 int tmp;
1157 tmp = (f[0] >> (i & 0x7)) & 1;
1158 HDR += tmp << i ;
1159 }
1160
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001161 usc_frame->pBuffer = rtp_frame->buf;
1162 usc_frame->nbytes = rtp_frame->size;
1163 usc_frame->bitrate = HDR == 0? 6300 : 5300;
1164 usc_frame->frametype = 0;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001165}
1166
1167static pj_status_t parse_g723(ipp_private_t *codec_data, void *pkt,
1168 pj_size_t pkt_size, const pj_timestamp *ts,
1169 unsigned *frame_cnt, pjmedia_frame frames[])
1170{
1171 unsigned count = 0;
1172 pj_uint8_t *f = (pj_uint8_t*)pkt;
1173
1174 while (pkt_size && count < *frame_cnt) {
1175 int framesize, i, j;
1176 int HDR = 0;
1177
1178 for (i = 0; i < 2; ++i){
1179 j = (f[0] >> (i & 0x7)) & 1;
1180 HDR += j << i ;
1181 }
1182
1183 if (HDR == 0)
1184 framesize = 24;
1185 else if (HDR == 1)
1186 framesize = 20;
1187 else if (HDR == 2)
1188 framesize = 4;
1189 else if (HDR == 3)
1190 framesize = 1;
1191 else {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001192 pj_assert(!"Unknown G723.1 frametype, packet may be corrupted!");
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001193 return PJMEDIA_CODEC_EINMODE;
1194 }
1195
1196 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;
1197 frames[count].buf = f;
1198 frames[count].size = framesize;
1199 frames[count].timestamp.u64 = ts->u64 + count *
1200 ipp_codec[codec_data->codec_idx].samples_per_frame;
1201
1202 f += framesize;
1203 pkt_size -= framesize;
1204
1205 ++count;
1206 }
1207
1208 *frame_cnt = count;
1209 return PJ_SUCCESS;
1210}
1211
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001212#endif /* PJMEDIA_HAS_INTEL_IPP_CODEC_G723_1 */
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001213
1214
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001215#if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001216
1217/* AMR bitstream sensitivity order map */
1218static pj_int16_t AMRNB_ordermap122[244] =
1219{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001220 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1221 10, 11, 12, 13, 14, 23, 15, 16, 17, 18,
1222 19, 20, 21, 22, 24, 25, 26, 27, 28, 38,
1223 141, 39, 142, 40, 143, 41, 144, 42, 145, 43,
1224 146, 44, 147, 45, 148, 46, 149, 47, 97, 150,
1225 200, 48, 98, 151, 201, 49, 99, 152, 202, 86,
1226 136, 189, 239, 87, 137, 190, 240, 88, 138, 191,
1227 241, 91, 194, 92, 195, 93, 196, 94, 197, 95,
1228 198, 29, 30, 31, 32, 33, 34, 35, 50, 100,
1229 153, 203, 89, 139, 192, 242, 51, 101, 154, 204,
1230 55, 105, 158, 208, 90, 140, 193, 243, 59, 109,
1231 162, 212, 63, 113, 166, 216, 67, 117, 170, 220,
1232 36, 37, 54, 53, 52, 58, 57, 56, 62, 61,
1233 60, 66, 65, 64, 70, 69, 68, 104, 103, 102,
1234 108, 107, 106, 112, 111, 110, 116, 115, 114, 120,
1235 119, 118, 157, 156, 155, 161, 160, 159, 165, 164,
1236 163, 169, 168, 167, 173, 172, 171, 207, 206, 205,
1237 211, 210, 209, 215, 214, 213, 219, 218, 217, 223,
1238 222, 221, 73, 72, 71, 76, 75, 74, 79, 78,
1239 77, 82, 81, 80, 85, 84, 83, 123, 122, 121,
1240 126, 125, 124, 129, 128, 127, 132, 131, 130, 135,
1241 134, 133, 176, 175, 174, 179, 178, 177, 182, 181,
1242 180, 185, 184, 183, 188, 187, 186, 226, 225, 224,
1243 229, 228, 227, 232, 231, 230, 235, 234, 233, 238,
1244 237, 236, 96, 199
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001245};
1246
1247static pj_int16_t AMRNB_ordermap102[204] =
1248{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001249 7, 6, 5, 4, 3, 2, 1, 0, 16, 15,
1250 14, 13, 12, 11, 10, 9, 8, 26, 27, 28,
1251 29, 30, 31, 115, 116, 117, 118, 119, 120, 72,
1252 73, 161, 162, 65, 68, 69, 108, 111, 112, 154,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001253 157, 158, 197, 200, 201, 32, 33, 121, 122, 74,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001254 75, 163, 164, 66, 109, 155, 198, 19, 23, 21,
1255 22, 18, 17, 20, 24, 25, 37, 36, 35, 34,
1256 80, 79, 78, 77, 126, 125, 124, 123, 169, 168,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001257 167, 166, 70, 67, 71, 113, 110, 114, 159, 156,
1258 160, 202, 199, 203, 76, 165, 81, 82, 92, 91,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001259 93, 83, 95, 85, 84, 94, 101, 102, 96, 104,
1260 86, 103, 87, 97, 127, 128, 138, 137, 139, 129,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001261 141, 131, 130, 140, 147, 148, 142, 150, 132, 149,
1262 133, 143, 170, 171, 181, 180, 182, 172, 184, 174,
1263 173, 183, 190, 191, 185, 193, 175, 192, 176, 186,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001264 38, 39, 49, 48, 50, 40, 52, 42, 41, 51,
1265 58, 59, 53, 61, 43, 60, 44, 54, 194, 179,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001266 189, 196, 177, 195, 178, 187, 188, 151, 136, 146,
1267 153, 134, 152, 135, 144, 145, 105, 90, 100, 107,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001268 88, 106, 89, 98, 99, 62, 47, 57, 64, 45,
1269 63, 46, 55, 56
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001270};
1271
1272static pj_int16_t AMRNB_ordermap795[159] =
1273{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001274 8, 7, 6, 5, 4, 3, 2, 14, 16, 9,
1275 10, 12, 13, 15, 11, 17, 20, 22, 24, 23,
1276 19, 18, 21, 56, 88, 122, 154, 57, 89, 123,
1277 155, 58, 90, 124, 156, 52, 84, 118, 150, 53,
1278 85, 119, 151, 27, 93, 28, 94, 29, 95, 30,
1279 96, 31, 97, 61, 127, 62, 128, 63, 129, 59,
1280 91, 125, 157, 32, 98, 64, 130, 1, 0, 25,
1281 26, 33, 99, 34, 100, 65, 131, 66, 132, 54,
1282 86, 120, 152, 60, 92, 126, 158, 55, 87, 121,
1283 153, 117, 116, 115, 46, 78, 112, 144, 43, 75,
1284 109, 141, 40, 72, 106, 138, 36, 68, 102, 134,
1285 114, 149, 148, 147, 146, 83, 82, 81, 80, 51,
1286 50, 49, 48, 47, 45, 44, 42, 39, 35, 79,
1287 77, 76, 74, 71, 67, 113, 111, 110, 108, 105,
1288 101, 145, 143, 142, 140, 137, 133, 41, 73, 107,
1289 139, 37, 69, 103, 135, 38, 70, 104, 136
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001290
1291};
1292
1293static pj_int16_t AMRNB_ordermap74[148] =
1294{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001295 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1296 10, 11, 12, 13, 14, 15, 16, 26, 87, 27,
1297 88, 28, 89, 29, 90, 30, 91, 51, 80, 112,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001298 141, 52, 81, 113, 142, 54, 83, 115, 144, 55,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001299 84, 116, 145, 58, 119, 59, 120, 21, 22, 23,
1300 17, 18, 19, 31, 60, 92, 121, 56, 85, 117,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001301 146, 20, 24, 25, 50, 79, 111, 140, 57, 86,
1302 118, 147, 49, 78, 110, 139, 48, 77, 53, 82,
1303 114, 143, 109, 138, 47, 76, 108, 137, 32, 33,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001304 61, 62, 93, 94, 122, 123, 41, 42, 43, 44,
1305 45, 46, 70, 71, 72, 73, 74, 75, 102, 103,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001306 104, 105, 106, 107, 131, 132, 133, 134, 135, 136,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001307 34, 63, 95, 124, 35, 64, 96, 125, 36, 65,
1308 97, 126, 37, 66, 98, 127, 38, 67, 99, 128,
1309 39, 68, 100, 129, 40, 69, 101, 130
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001310};
1311
1312static pj_int16_t AMRNB_ordermap67[134] =
1313{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001314 0, 1, 4, 3, 5, 6, 13, 7, 2, 8,
1315 9, 11, 15, 12, 14, 10, 28, 82, 29, 83,
1316 27, 81, 26, 80, 30, 84, 16, 55, 109, 56,
1317 110, 31, 85, 57, 111, 48, 73, 102, 127, 32,
1318 86, 51, 76, 105, 130, 52, 77, 106, 131, 58,
1319 112, 33, 87, 19, 23, 53, 78, 107, 132, 21,
1320 22, 18, 17, 20, 24, 25, 50, 75, 104, 129,
1321 47, 72, 101, 126, 54, 79, 108, 133, 46, 71,
1322 100, 125, 128, 103, 74, 49, 45, 70, 99, 124,
1323 42, 67, 96, 121, 39, 64, 93, 118, 38, 63,
1324 92, 117, 35, 60, 89, 114, 34, 59, 88, 113,
1325 44, 69, 98, 123, 43, 68, 97, 122, 41, 66,
1326 95, 120, 40, 65, 94, 119, 37, 62, 91, 116,
1327 36, 61, 90, 115
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001328};
1329
1330static pj_int16_t AMRNB_ordermap59[118] =
1331{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001332 0, 1, 4, 5, 3, 6, 7, 2, 13, 15,
1333 8, 9, 11, 12, 14, 10, 16, 28, 74, 29,
1334 75, 27, 73, 26, 72, 30, 76, 51, 97, 50,
1335 71, 96, 117, 31, 77, 52, 98, 49, 70, 95,
1336 116, 53, 99, 32, 78, 33, 79, 48, 69, 94,
1337 115, 47, 68, 93, 114, 46, 67, 92, 113, 19,
1338 21, 23, 22, 18, 17, 20, 24, 111, 43, 89,
1339 110, 64, 65, 44, 90, 25, 45, 66, 91, 112,
1340 54, 100, 40, 61, 86, 107, 39, 60, 85, 106,
1341 36, 57, 82, 103, 35, 56, 81, 102, 34, 55,
1342 80, 101, 42, 63, 88, 109, 41, 62, 87, 108,
1343 38, 59, 84, 105, 37, 58, 83, 104
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001344};
1345
1346static pj_int16_t AMRNB_ordermap515[103] =
1347{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001348 7, 6, 5, 4, 3, 2, 1, 0, 15, 14,
1349 13, 12, 11, 10, 9, 8, 23, 24, 25, 26,
1350 27, 46, 65, 84, 45, 44, 43, 64, 63, 62,
1351 83, 82, 81, 102, 101, 100, 42, 61, 80, 99,
1352 28, 47, 66, 85, 18, 41, 60, 79, 98, 29,
1353 48, 67, 17, 20, 22, 40, 59, 78, 97, 21,
1354 30, 49, 68, 86, 19, 16, 87, 39, 38, 58,
1355 57, 77, 35, 54, 73, 92, 76, 96, 95, 36,
1356 55, 74, 93, 32, 51, 33, 52, 70, 71, 89,
1357 90, 31, 50, 69, 88, 37, 56, 75, 94, 34,
1358 53, 72, 91
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001359};
1360
1361static pj_int16_t AMRNB_ordermap475[95] =
1362{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001363 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
1364 10, 11, 12, 13, 14, 15, 23, 24, 25, 26,
1365 27, 28, 48, 49, 61, 62, 82, 83, 47, 46,
1366 45, 44, 81, 80, 79, 78, 17, 18, 20, 22,
1367 77, 76, 75, 74, 29, 30, 43, 42, 41, 40,
1368 38, 39, 16, 19, 21, 50, 51, 59, 60, 63,
1369 64, 72, 73, 84, 85, 93, 94, 32, 33, 35,
1370 36, 53, 54, 56, 57, 66, 67, 69, 70, 87,
1371 88, 90, 91, 34, 55, 68, 89, 37, 58, 71,
1372 92, 31, 52, 65, 86
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001373};
1374
1375static pj_int16_t *AMRNB_ordermaps[8] =
1376{
1377 AMRNB_ordermap475,
1378 AMRNB_ordermap515,
1379 AMRNB_ordermap59,
1380 AMRNB_ordermap67,
1381 AMRNB_ordermap74,
1382 AMRNB_ordermap795,
1383 AMRNB_ordermap102,
1384 AMRNB_ordermap122
1385};
1386
1387static pj_int16_t AMRWB_ordermap_660[] =
1388{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001389 0, 5, 6, 7, 61, 84, 107, 130, 62, 85,
1390 8, 4, 37, 38, 39, 40, 58, 81, 104, 127,
1391 60, 83, 106, 129, 108, 131, 128, 41, 42, 80,
1392 126, 1, 3, 57, 103, 82, 105, 59, 2, 63,
1393 109, 110, 86, 19, 22, 23, 64, 87, 18, 20,
1394 21, 17, 13, 88, 43, 89, 65, 111, 14, 24,
1395 25, 26, 27, 28, 15, 16, 44, 90, 66, 112,
1396 9, 11, 10, 12, 67, 113, 29, 30, 31, 32,
1397 34, 33, 35, 36, 45, 51, 68, 74, 91, 97,
1398 114, 120, 46, 69, 92, 115, 52, 75, 98, 121,
1399 47, 70, 93, 116, 53, 76, 99, 122, 48, 71,
1400 94, 117, 54, 77, 100, 123, 49, 72, 95, 118,
1401 55, 78, 101, 124, 50, 73, 96, 119, 56, 79,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001402 102, 125
1403};
1404
1405static pj_int16_t AMRWB_ordermap_885[] =
1406{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001407 0, 4, 6, 7, 5, 3, 47, 48, 49, 112,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001408 113, 114, 75, 106, 140, 171, 80, 111, 145, 176,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001409 77, 108, 142, 173, 78, 109, 143, 174, 79, 110,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001410 144, 175, 76, 107, 141, 172, 50, 115, 51, 2,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001411 1, 81, 116, 146, 19, 21, 12, 17, 18, 20,
1412 16, 25, 13, 10, 14, 24, 23, 22, 26, 8,
1413 15, 52, 117, 31, 82, 147, 9, 33, 11, 83,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001414 148, 53, 118, 28, 27, 84, 149, 34, 35, 29,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001415 46, 32, 30, 54, 119, 37, 36, 39, 38, 40,
1416 85, 150, 41, 42, 43, 44, 45, 55, 60, 65,
1417 70, 86, 91, 96, 101, 120, 125, 130, 135, 151,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001418 156, 161, 166, 56, 87, 121, 152, 61, 92, 126,
1419 157, 66, 97, 131, 162, 71, 102, 136, 167, 57,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001420 88, 122, 153, 62, 93, 127, 158, 67, 98, 132,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001421 163, 72, 103, 137, 168, 58, 89, 123, 154, 63,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001422 94, 128, 159, 68, 99, 133, 164, 73, 104, 138,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001423 169, 59, 90, 124, 155, 64, 95, 129, 160, 69,
1424 100, 134, 165, 74, 105, 139, 170
1425};
1426
1427static pj_int16_t AMRWB_ordermap_1265[] =
1428{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001429 0, 4, 6, 93, 143, 196, 246, 7, 5, 3,
1430 47, 48, 49, 50, 51, 150, 151, 152, 153, 154,
1431 94, 144, 197, 247, 99, 149, 202, 252, 96, 146,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001432 199, 249, 97, 147, 200, 250, 100, 203, 98, 148,
1433 201, 251, 95, 145, 198, 248, 52, 2, 1, 101,
1434 204, 155, 19, 21, 12, 17, 18, 20, 16, 25,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001435 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001436 156, 31, 102, 205, 9, 33, 11, 103, 206, 54,
1437 157, 28, 27, 104, 207, 34, 35, 29, 46, 32,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001438 30, 55, 158, 37, 36, 39, 38, 40, 105, 208,
1439 41, 42, 43, 44, 45, 56, 106, 159, 209, 57,
1440 66, 75, 84, 107, 116, 125, 134, 160, 169, 178,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001441 187, 210, 219, 228, 237, 58, 108, 161, 211, 62,
1442 112, 165, 215, 67, 117, 170, 220, 71, 121, 174,
1443 224, 76, 126, 179, 229, 80, 130, 183, 233, 85,
1444 135, 188, 238, 89, 139, 192, 242, 59, 109, 162,
1445 212, 63, 113, 166, 216, 68, 118, 171, 221, 72,
1446 122, 175, 225, 77, 127, 180, 230, 81, 131, 184,
1447 234, 86, 136, 189, 239, 90, 140, 193, 243, 60,
1448 110, 163, 213, 64, 114, 167, 217, 69, 119, 172,
1449 222, 73, 123, 176, 226, 78, 128, 181, 231, 82,
1450 132, 185, 235, 87, 137, 190, 240, 91, 141, 194,
1451 244, 61, 111, 164, 214, 65, 115, 168, 218, 70,
1452 120, 173, 223, 74, 124, 177, 227, 79, 129, 182,
1453 232, 83, 133, 186, 236, 88, 138, 191, 241, 92,
1454 142, 195, 245
1455};
1456
1457static pj_int16_t AMRWB_ordermap_1425[] =
1458{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001459 0, 4, 6, 101, 159, 220, 278, 7, 5, 3,
1460 47, 48, 49, 50, 51, 166, 167, 168, 169, 170,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001461 102, 160, 221, 279, 107, 165, 226, 284, 104, 162,
1462 223, 281, 105, 163, 224, 282, 108, 227, 106, 164,
1463 225, 283, 103, 161, 222, 280, 52, 2, 1, 109,
1464 228, 171, 19, 21, 12, 17, 18, 20, 16, 25,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001465 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001466 172, 31, 110, 229, 9, 33, 11, 111, 230, 54,
1467 173, 28, 27, 112, 231, 34, 35, 29, 46, 32,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001468 30, 55, 174, 37, 36, 39, 38, 40, 113, 232,
1469 41, 42, 43, 44, 45, 56, 114, 175, 233, 62,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001470 120, 181, 239, 75, 133, 194, 252, 57, 115, 176,
1471 234, 63, 121, 182, 240, 70, 128, 189, 247, 76,
1472 134, 195, 253, 83, 141, 202, 260, 92, 150, 211,
1473 269, 84, 142, 203, 261, 93, 151, 212, 270, 85,
1474 143, 204, 262, 94, 152, 213, 271, 86, 144, 205,
1475 263, 95, 153, 214, 272, 64, 122, 183, 241, 77,
1476 135, 196, 254, 65, 123, 184, 242, 78, 136, 197,
1477 255, 87, 145, 206, 264, 96, 154, 215, 273, 58,
1478 116, 177, 235, 66, 124, 185, 243, 71, 129, 190,
1479 248, 79, 137, 198, 256, 88, 146, 207, 265, 97,
1480 155, 216, 274, 59, 117, 178, 236, 67, 125, 186,
1481 244, 72, 130, 191, 249, 80, 138, 199, 257, 89,
1482 147, 208, 266, 98, 156, 217, 275, 60, 118, 179,
1483 237, 68, 126, 187, 245, 73, 131, 192, 250, 81,
1484 139, 200, 258, 90, 148, 209, 267, 99, 157, 218,
1485 276, 61, 119, 180, 238, 69, 127, 188, 246, 74,
1486 132, 193, 251, 82, 140, 201, 259, 91, 149, 210,
1487 268, 100, 158, 219, 277
1488};
1489
1490static pj_int16_t AMRWB_ordermap_1585[] =
1491{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001492 0, 4, 6, 109, 175, 244, 310, 7, 5, 3,
1493 47, 48, 49, 50, 51, 182, 183, 184, 185, 186,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001494 110, 176, 245, 311, 115, 181, 250, 316, 112, 178,
1495 247, 313, 113, 179, 248, 314, 116, 251, 114, 180,
1496 249, 315, 111, 177, 246, 312, 52, 2, 1, 117,
1497 252, 187, 19, 21, 12, 17, 18, 20, 16, 25,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001498 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001499 188, 31, 118, 253, 9, 33, 11, 119, 254, 54,
1500 189, 28, 27, 120, 255, 34, 35, 29, 46, 32,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001501 30, 55, 190, 37, 36, 39, 38, 40, 121, 256,
1502 41, 42, 43, 44, 45, 56, 122, 191, 257, 63,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001503 129, 198, 264, 76, 142, 211, 277, 89, 155, 224,
1504 290, 102, 168, 237, 303, 57, 123, 192, 258, 70,
1505 136, 205, 271, 83, 149, 218, 284, 96, 162, 231,
1506 297, 62, 128, 197, 263, 75, 141, 210, 276, 88,
1507 154, 223, 289, 101, 167, 236, 302, 58, 124, 193,
1508 259, 71, 137, 206, 272, 84, 150, 219, 285, 97,
1509 163, 232, 298, 59, 125, 194, 260, 64, 130, 199,
1510 265, 67, 133, 202, 268, 72, 138, 207, 273, 77,
1511 143, 212, 278, 80, 146, 215, 281, 85, 151, 220,
1512 286, 90, 156, 225, 291, 93, 159, 228, 294, 98,
1513 164, 233, 299, 103, 169, 238, 304, 106, 172, 241,
1514 307, 60, 126, 195, 261, 65, 131, 200, 266, 68,
1515 134, 203, 269, 73, 139, 208, 274, 78, 144, 213,
1516 279, 81, 147, 216, 282, 86, 152, 221, 287, 91,
1517 157, 226, 292, 94, 160, 229, 295, 99, 165, 234,
1518 300, 104, 170, 239, 305, 107, 173, 242, 308, 61,
1519 127, 196, 262, 66, 132, 201, 267, 69, 135, 204,
1520 270, 74, 140, 209, 275, 79, 145, 214, 280, 82,
1521 148, 217, 283, 87, 153, 222, 288, 92, 158, 227,
1522 293, 95, 161, 230, 296, 100, 166, 235, 301, 105,
1523 171, 240, 306, 108, 174, 243, 309
1524};
1525
1526static pj_int16_t AMRWB_ordermap_1825[] =
1527{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001528 0, 4, 6, 121, 199, 280, 358, 7, 5, 3,
1529 47, 48, 49, 50, 51, 206, 207, 208, 209, 210,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001530 122, 200, 281, 359, 127, 205, 286, 364, 124, 202,
1531 283, 361, 125, 203, 284, 362, 128, 287, 126, 204,
1532 285, 363, 123, 201, 282, 360, 52, 2, 1, 129,
1533 288, 211, 19, 21, 12, 17, 18, 20, 16, 25,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001534 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001535 212, 31, 130, 289, 9, 33, 11, 131, 290, 54,
1536 213, 28, 27, 132, 291, 34, 35, 29, 46, 32,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001537 30, 55, 214, 37, 36, 39, 38, 40, 133, 292,
1538 41, 42, 43, 44, 45, 56, 134, 215, 293, 198,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001539 299, 136, 120, 138, 60, 279, 58, 62, 357, 139,
1540 140, 295, 156, 57, 219, 297, 63, 217, 137, 170,
1541 300, 222, 64, 106, 61, 78, 294, 92, 142, 141,
1542 135, 221, 296, 301, 343, 59, 298, 184, 329, 315,
1543 220, 216, 265, 251, 218, 237, 352, 223, 157, 86,
1544 171, 87, 164, 351, 111, 302, 65, 178, 115, 323,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001545 72, 192, 101, 179, 93, 73, 193, 151, 337, 309,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001546 143, 274, 69, 324, 165, 150, 97, 338, 110, 310,
1547 330, 273, 68, 107, 175, 245, 114, 79, 113, 189,
1548 246, 259, 174, 71, 185, 96, 344, 100, 322, 83,
1549 334, 316, 333, 252, 161, 348, 147, 82, 269, 232,
1550 260, 308, 353, 347, 163, 231, 306, 320, 188, 270,
1551 146, 177, 266, 350, 256, 85, 149, 116, 191, 160,
1552 238, 258, 336, 305, 255, 88, 224, 99, 339, 230,
1553 228, 227, 272, 242, 241, 319, 233, 311, 102, 74,
1554 180, 275, 66, 194, 152, 325, 172, 247, 244, 261,
1555 117, 158, 166, 354, 75, 144, 108, 312, 94, 186,
1556 303, 80, 234, 89, 195, 112, 340, 181, 345, 317,
1557 326, 276, 239, 167, 118, 313, 70, 355, 327, 253,
1558 190, 176, 271, 104, 98, 153, 103, 90, 76, 267,
1559 277, 248, 225, 262, 182, 84, 154, 235, 335, 168,
1560 331, 196, 341, 249, 162, 307, 148, 349, 263, 321,
1561 257, 243, 229, 356, 159, 119, 67, 187, 173, 145,
1562 240, 77, 304, 332, 314, 342, 109, 254, 81, 278,
1563 105, 91, 346, 318, 183, 250, 197, 328, 95, 155,
1564 169, 268, 226, 236, 264
1565};
1566
1567static pj_int16_t AMRWB_ordermap_1985[] =
1568{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001569 0, 4, 6, 129, 215, 304, 390, 7, 5, 3,
1570 47, 48, 49, 50, 51, 222, 223, 224, 225, 226,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001571 130, 216, 305, 391, 135, 221, 310, 396, 132, 218,
1572 307, 393, 133, 219, 308, 394, 136, 311, 134, 220,
1573 309, 395, 131, 217, 306, 392, 52, 2, 1, 137,
1574 312, 227, 19, 21, 12, 17, 18, 20, 16, 25,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001575 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001576 228, 31, 138, 313, 9, 33, 11, 139, 314, 54,
1577 229, 28, 27, 140, 315, 34, 35, 29, 46, 32,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001578 30, 55, 230, 37, 36, 39, 38, 40, 141, 316,
1579 41, 42, 43, 44, 45, 56, 142, 231, 317, 63,
1580 73, 92, 340, 82, 324, 149, 353, 159, 334, 165,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001581 338, 178, 163, 254, 77, 168, 257, 153, 343, 57,
1582 248, 238, 79, 252, 166, 67, 80, 201, 101, 267,
1583 143, 164, 341, 255, 339, 187, 376, 318, 78, 328,
1584 362, 115, 232, 242, 253, 290, 276, 62, 58, 158,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001585 68, 93, 179, 319, 148, 169, 154, 72, 385, 329,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001586 333, 344, 102, 83, 144, 233, 323, 124, 243, 192,
1587 354, 237, 64, 247, 202, 209, 150, 116, 335, 268,
1588 239, 299, 188, 196, 298, 94, 195, 258, 123, 363,
1589 384, 109, 325, 371, 170, 370, 84, 110, 295, 180,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001590 74, 210, 191, 106, 291, 205, 367, 381, 377, 206,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001591 355, 122, 119, 120, 383, 160, 105, 108, 277, 380,
1592 294, 284, 285, 345, 208, 269, 249, 366, 386, 300,
1593 297, 259, 125, 369, 197, 97, 194, 286, 211, 281,
1594 280, 183, 372, 87, 155, 283, 59, 348, 327, 184,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001595 76, 111, 330, 203, 349, 69, 98, 152, 145, 189,
1596 66, 320, 337, 173, 358, 251, 198, 174, 263, 262,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001597 126, 241, 193, 88, 388, 117, 95, 387, 112, 359,
1598 287, 244, 103, 272, 301, 171, 162, 234, 273, 127,
1599 373, 181, 292, 85, 378, 302, 121, 107, 364, 346,
1600 356, 212, 278, 213, 65, 382, 288, 207, 113, 175,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001601 99, 296, 374, 368, 199, 260, 185, 336, 331, 161,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001602 270, 264, 250, 240, 75, 350, 151, 60, 89, 321,
1603 156, 274, 360, 326, 70, 282, 167, 146, 352, 81,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001604 91, 389, 266, 245, 177, 235, 190, 256, 204, 342,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001605 128, 118, 303, 104, 379, 182, 114, 375, 200, 96,
1606 293, 172, 214, 365, 279, 86, 289, 351, 347, 357,
1607 261, 186, 176, 271, 90, 100, 147, 322, 275, 361,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001608 71, 332, 61, 265, 157, 246, 236
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001609};
1610
1611static pj_int16_t AMRWB_ordermap_2305[] =
1612{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001613 0, 4, 6, 145, 247, 352, 454, 7, 5, 3,
1614 47, 48, 49, 50, 51, 254, 255, 256, 257, 258,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001615 146, 248, 353, 455, 151, 253, 358, 460, 148, 250,
1616 355, 457, 149, 251, 356, 458, 152, 359, 150, 252,
1617 357, 459, 147, 249, 354, 456, 52, 2, 1, 153,
1618 360, 259, 19, 21, 12, 17, 18, 20, 16, 25,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001619 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001620 260, 31, 154, 361, 9, 33, 11, 155, 362, 54,
1621 261, 28, 27, 156, 363, 34, 35, 29, 46, 32,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001622 30, 55, 262, 37, 36, 39, 38, 40, 157, 364,
1623 41, 42, 43, 44, 45, 56, 158, 263, 365, 181,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001624 192, 170, 79, 57, 399, 90, 159, 297, 377, 366,
1625 275, 68, 183, 388, 286, 194, 299, 92, 70, 182,
1626 401, 172, 59, 91, 58, 400, 368, 161, 81, 160,
1627 264, 171, 80, 389, 390, 378, 379, 193, 298, 69,
1628 266, 265, 367, 277, 288, 276, 287, 184, 60, 195,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001629 82, 93, 71, 369, 402, 173, 162, 444, 300, 391,
1630 98, 76, 278, 61, 267, 374, 135, 411, 167, 102,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001631 380, 200, 87, 178, 65, 94, 204, 124, 72, 342,
1632 189, 305, 381, 396, 433, 301, 226, 407, 289, 237,
1633 113, 215, 185, 128, 309, 403, 116, 320, 196, 331,
1634 370, 422, 174, 64, 392, 83, 425, 219, 134, 188,
1635 432, 112, 427, 139, 279, 163, 436, 208, 447, 218,
1636 236, 229, 97, 294, 385, 230, 166, 268, 177, 443,
1637 225, 426, 101, 272, 138, 127, 290, 117, 347, 199,
1638 414, 95, 140, 240, 410, 395, 209, 129, 283, 346,
1639 105, 241, 437, 86, 308, 448, 203, 345, 186, 107,
1640 220, 415, 334, 319, 106, 313, 118, 123, 73, 207,
1641 421, 214, 384, 373, 438, 62, 371, 341, 75, 449,
1642 168, 323, 164, 242, 416, 324, 304, 197, 335, 404,
1643 271, 63, 191, 325, 96, 169, 231, 280, 312, 187,
1644 406, 84, 201, 100, 67, 382, 175, 336, 202, 330,
1645 269, 393, 376, 383, 293, 307, 409, 179, 285, 314,
1646 302, 372, 398, 190, 180, 89, 99, 103, 232, 78,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001647 88, 77, 136, 387, 165, 198, 394, 125, 176, 428,
1648 74, 375, 238, 227, 66, 273, 282, 141, 306, 412,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001649 114, 85, 130, 348, 119, 291, 296, 386, 233, 397,
1650 303, 405, 284, 445, 423, 221, 210, 205, 450, 108,
1651 274, 434, 216, 343, 337, 142, 243, 321, 408, 451,
1652 310, 292, 120, 109, 281, 439, 270, 429, 332, 295,
1653 418, 211, 315, 222, 326, 131, 430, 244, 327, 349,
1654 417, 316, 143, 338, 440, 234, 110, 212, 452, 245,
1655 121, 419, 350, 223, 132, 441, 328, 413, 317, 339,
1656 126, 104, 137, 446, 344, 239, 435, 115, 333, 206,
1657 322, 217, 228, 424, 453, 311, 351, 111, 442, 224,
1658 213, 122, 431, 340, 235, 246, 133, 144, 420, 329,
1659 318
1660};
1661
1662static pj_int16_t AMRWB_ordermap_2385[] =
1663{
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001664 0, 4, 6, 145, 251, 360, 466, 7, 5, 3,
1665 47, 48, 49, 50, 51, 262, 263, 264, 265, 266,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001666 146, 252, 361, 467, 151, 257, 366, 472, 148, 254,
1667 363, 469, 149, 255, 364, 470, 156, 371, 150, 256,
1668 365, 471, 147, 253, 362, 468, 52, 2, 1, 157,
1669 372, 267, 19, 21, 12, 17, 18, 20, 16, 25,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001670 13, 10, 14, 24, 23, 22, 26, 8, 15, 53,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001671 268, 31, 152, 153, 154, 155, 258, 259, 260, 261,
1672 367, 368, 369, 370, 473, 474, 475, 476, 158, 373,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001673 9, 33, 11, 159, 374, 54, 269, 28, 27, 160,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001674 375, 34, 35, 29, 46, 32, 30, 55, 270, 37,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001675 36, 39, 38, 40, 161, 376, 41, 42, 43, 44,
1676 45, 56, 162, 271, 377, 185, 196, 174, 79, 57,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001677 411, 90, 163, 305, 389, 378, 283, 68, 187, 400,
1678 294, 198, 307, 92, 70, 186, 413, 176, 59, 91,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001679 58, 412, 380, 165, 81, 164, 272, 175, 80, 401,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001680 402, 390, 391, 197, 306, 69, 274, 273, 379, 285,
1681 296, 284, 295, 188, 60, 199, 82, 93, 71, 381,
1682 414, 177, 166, 456, 308, 403, 98, 76, 286, 61,
1683 275, 386, 135, 423, 171, 102, 392, 204, 87, 182,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001684 65, 94, 208, 124, 72, 350, 193, 313, 393, 408,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001685 445, 309, 230, 419, 297, 241, 113, 219, 189, 128,
1686 317, 415, 116, 328, 200, 339, 382, 434, 178, 64,
1687 404, 83, 437, 223, 134, 192, 444, 112, 439, 139,
1688 287, 167, 448, 212, 459, 222, 240, 233, 97, 302,
1689 397, 234, 170, 276, 181, 455, 229, 438, 101, 280,
1690 138, 127, 298, 117, 355, 203, 426, 95, 140, 244,
1691 422, 407, 213, 129, 291, 354, 105, 245, 449, 86,
1692 316, 460, 207, 353, 190, 107, 224, 427, 342, 327,
1693 106, 321, 118, 123, 73, 211, 433, 218, 396, 385,
1694 450, 62, 383, 349, 75, 461, 172, 331, 168, 246,
1695 428, 332, 312, 201, 343, 416, 279, 63, 195, 333,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001696 96, 173, 235, 288, 320, 191, 418, 84, 205, 100,
1697 67, 394, 179, 344, 206, 338, 277, 405, 388, 395,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001698 301, 315, 421, 183, 293, 322, 310, 384, 410, 194,
1699 184, 89, 99, 103, 236, 78, 88, 77, 136, 399,
1700 169, 202, 406, 125, 180, 440, 74, 387, 242, 231,
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001701 66, 281, 290, 141, 314, 424, 114, 85, 130, 356,
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001702 119, 299, 304, 398, 237, 409, 311, 417, 292, 457,
1703 435, 225, 214, 209, 462, 108, 282, 446, 220, 351,
1704 345, 142, 247, 329, 420, 463, 318, 300, 120, 109,
1705 289, 451, 278, 441, 340, 303, 430, 215, 323, 226,
1706 334, 131, 442, 248, 335, 357, 429, 324, 143, 346,
1707 452, 238, 110, 216, 464, 249, 121, 431, 358, 227,
1708 132, 453, 336, 425, 325, 347, 126, 104, 137, 458,
1709 352, 243, 447, 115, 341, 210, 330, 221, 232, 436,
1710 465, 319, 359, 111, 454, 228, 217, 122, 443, 348,
1711 239, 250, 133, 144, 432, 337, 326
1712};
1713
1714static pj_int16_t *AMRWB_ordermaps[9] =
1715{
1716 AMRWB_ordermap_660,
1717 AMRWB_ordermap_885,
1718 AMRWB_ordermap_1265,
1719 AMRWB_ordermap_1425,
1720 AMRWB_ordermap_1585,
1721 AMRWB_ordermap_1825,
1722 AMRWB_ordermap_1985,
1723 AMRWB_ordermap_2305,
1724 AMRWB_ordermap_2385
1725};
1726
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001727static pj_uint8_t AMRNB_framelen[16] =
1728 {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 5};
1729static pj_uint16_t AMRNB_framelenbits[9] =
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001730 {95, 103, 118, 134, 148, 159, 204, 244, 39};
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001731static pj_uint16_t AMRNB_bitrates[8] =
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001732 {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200};
1733
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001734static pj_uint8_t AMRWB_framelen[16] =
1735 {17, 23, 32, 37, 40, 46, 50, 58, 60, 5, 0, 0, 0, 0, 0, 5};
1736static pj_uint16_t AMRWB_framelenbits[10] =
1737 {132, 177, 253, 285, 317, 365, 397, 461, 477, 40};
1738static pj_uint16_t AMRWB_bitrates[9] =
1739 {6600, 8850, 12650, 14250, 15850, 18250, 19850, 23050, 23850};
1740
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001741
1742/* Get mode based on bitrate */
1743static int amr_get_mode(unsigned bitrate)
1744{
1745 int mode = -1;
1746
1747 if(bitrate==4750){
1748 mode = 0;
1749 } else if(bitrate==5150){
1750 mode = 1;
1751 } else if(bitrate==5900){
1752 mode = 2;
1753 } else if(bitrate==6700){
1754 mode = 3;
1755 } else if(bitrate==7400){
1756 mode = 4;
1757 } else if(bitrate==7950){
1758 mode = 5;
1759 } else if(bitrate==10200){
1760 mode = 6;
1761 } else if(bitrate==12200){
1762 mode = 7;
1763
1764 /* AMRWB */
1765 } else if(bitrate==6600){
1766 mode = 0;
1767 } else if(bitrate==8850){
1768 mode = 1;
1769 } else if(bitrate==12650){
1770 mode = 2;
1771 } else if(bitrate==14250){
1772 mode = 3;
1773 } else if(bitrate==15850){
1774 mode = 4;
1775 } else if(bitrate==18250){
1776 mode = 5;
1777 } else if(bitrate==19850){
1778 mode = 6;
1779 } else if(bitrate==23050){
1780 mode = 7;
1781 } else if(bitrate==23850){
1782 mode = 8;
1783 }
1784 return mode;
1785}
1786
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001787/* Rearrange AMR bitstream of rtp_frame:
1788 * - make the start_bit to be 0
1789 * - if it is speech frame, reorder bitstream from sensitivity bits order
1790 * to encoder bits order.
1791 */
1792static void predecode_amr( ipp_private_t *codec_data,
1793 const pjmedia_frame *rtp_frame,
1794 USC_Bitstream *usc_frame)
1795{
1796 pj_uint8_t FT, Q;
1797 pj_int8_t amr_bits[477 + 7] = {0};
1798 pj_int8_t *p_amr_bits = &amr_bits[0];
1799 unsigned i;
1800 /* read cursor */
1801 pj_uint8_t *r = (pj_uint8_t*)rtp_frame->buf;
1802 pj_uint8_t start_bit;
1803 /* write cursor */
1804 pj_uint8_t *w = (pj_uint8_t*)rtp_frame->buf;
1805 /* env vars for AMR or AMRWB */
1806 pj_bool_t AMRWB;
1807 pj_uint8_t SID_FT = 8;
1808 pj_uint8_t *framelen_tbl = AMRNB_framelen;
1809 pj_uint16_t *framelenbit_tbl = AMRNB_framelenbits;
1810 pj_uint16_t *bitrate_tbl = AMRNB_bitrates;
1811 pj_int16_t **order_map = AMRNB_ordermaps;
1812
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001813 AMRWB = (ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMRWB);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001814 if (AMRWB) {
1815 SID_FT = 9;
1816 framelen_tbl = AMRWB_framelen;
1817 framelenbit_tbl = AMRWB_framelenbits;
1818 bitrate_tbl = AMRWB_bitrates;
1819 order_map = AMRWB_ordermaps;
1820 }
1821
1822 start_bit = (pj_uint8_t)((rtp_frame->bit_info & 0x0700) >> 8);
1823 FT = (pj_uint8_t)(rtp_frame->bit_info & 0x0F);
1824 Q = (pj_uint8_t)((rtp_frame->bit_info >> 16) & 0x01);
1825
1826 /* unpack AMR bitstream if there is any data */
1827 if (FT <= SID_FT) {
1828 i = 0;
1829 if (start_bit) {
1830 for (; i < (unsigned)(8-start_bit); ++i)
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001831 *p_amr_bits++ = (pj_uint8_t)((*r >> (7-start_bit-i)) & 1);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001832 ++r;
1833 }
1834 for(; i < framelenbit_tbl[FT]; i += 8) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001835 *p_amr_bits++ = (pj_uint8_t)((*r >> 7) & 1);
1836 *p_amr_bits++ = (pj_uint8_t)((*r >> 6) & 1);
1837 *p_amr_bits++ = (pj_uint8_t)((*r >> 5) & 1);
1838 *p_amr_bits++ = (pj_uint8_t)((*r >> 4) & 1);
1839 *p_amr_bits++ = (pj_uint8_t)((*r >> 3) & 1);
1840 *p_amr_bits++ = (pj_uint8_t)((*r >> 2) & 1);
1841 *p_amr_bits++ = (pj_uint8_t)((*r >> 1) & 1);
1842 *p_amr_bits++ = (pj_uint8_t)((*r ) & 1);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001843 ++r;
1844 }
1845 }
1846
1847 if (FT < SID_FT) {
1848 /* Speech */
1849 pj_int16_t *order_map_;
1850
1851 order_map_ = order_map[FT];
1852 pj_bzero(rtp_frame->buf, rtp_frame->size);
1853 for(i = 0; i < framelenbit_tbl[FT]; ++i) {
1854 if (amr_bits[i]) {
1855 pj_uint16_t bitpos;
1856 bitpos = order_map_[i];
1857 w[bitpos>>3] |= 1 << (7 - (bitpos % 8));
1858 }
1859 }
1860 usc_frame->nbytes = framelen_tbl[FT];
1861 if (Q)
1862 usc_frame->frametype = 0;
1863 else
1864 usc_frame->frametype = AMRWB ? 6 : 5;
1865 usc_frame->bitrate = bitrate_tbl[FT];
1866 } else if (FT == SID_FT) {
1867 /* SID */
1868 pj_uint8_t w_bitptr = 0;
1869 pj_uint8_t STI;
1870 pj_uint8_t FT_;
1871
1872 STI = amr_bits[35];
1873 if (AMRWB)
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001874 FT_ = (pj_uint8_t)((amr_bits[36] << 3) | (amr_bits[37] << 2) |
1875 (amr_bits[38] << 1) | amr_bits[39]);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001876 else
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001877 FT_ = (pj_uint8_t)((amr_bits[36] << 2) | (amr_bits[37] << 1) |
1878 amr_bits[38]);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001879
1880 pj_bzero(rtp_frame->buf, rtp_frame->size);
1881 for(i = 0; i < framelenbit_tbl[FT]; ++i) {
1882 if (amr_bits[i])
1883 *w |= (1 << (7-w_bitptr));
1884
1885 if (++w_bitptr == 8) {
1886 ++w;
1887 w_bitptr = 0;
1888 }
1889 }
1890
1891 usc_frame->nbytes = 5;
1892 if (Q)
1893 usc_frame->frametype = STI? 2 : 1;
1894 else
1895 usc_frame->frametype = AMRWB ? 7 : 6;
1896
1897 usc_frame->bitrate = bitrate_tbl[FT_];
1898 } else {
1899 /* NO DATA */
1900 usc_frame->nbytes = 0;
1901 usc_frame->frametype = 3;
1902 usc_frame->bitrate = 0;
1903 }
1904
1905 usc_frame->pBuffer = rtp_frame->buf;
1906}
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001907
1908static pj_status_t pack_amr(ipp_private_t *codec_data, void *pkt,
1909 pj_size_t *pkt_size, pj_size_t max_pkt_size)
1910{
1911 /* Settings */
1912 pj_uint8_t CMR = 15; /* We don't request any code mode */
1913 pj_uint8_t octet_aligned = 0; /* default==0 when SDP not specifying */
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001914 /* Write cursor */
1915 pj_uint8_t *w = (pj_uint8_t*)pkt;
1916 pj_uint8_t w_bitptr = 0;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001917 /* Read cursor */
1918 pj_uint8_t *r;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001919 /* env vars for AMR or AMRWB */
1920 pj_bool_t AMRWB;
1921 pj_uint8_t SID_FT = 8;
1922 pj_uint8_t *framelen_tbl = AMRNB_framelen;
1923 pj_uint16_t *framelenbit_tbl = AMRNB_framelenbits;
1924 pj_uint16_t *bitrate_tbl = AMRNB_bitrates;
1925 pj_int16_t **order_map = AMRNB_ordermaps;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001926
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001927 AMRWB = ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMRWB;
1928 if (AMRWB) {
1929 SID_FT = 9;
1930 framelen_tbl = AMRWB_framelen;
1931 framelenbit_tbl = AMRWB_framelenbits;
1932 bitrate_tbl = AMRWB_bitrates;
1933 order_map = AMRWB_ordermaps;
1934 }
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001935
1936 PJ_TODO(Make_sure_buffer_is_enough_for_packing_AMR_packet);
1937
1938 r = (pj_uint8_t*)pkt + max_pkt_size - *pkt_size;
1939
1940 /* Align pkt buf right */
1941 pj_memmove(r, w, *pkt_size);
1942
1943 /* Code Mode Request, 4 bits */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001944 *w = (pj_uint8_t)(CMR << 4);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001945 w_bitptr = 4;
1946 if (octet_aligned) {
1947 ++w;
1948 w_bitptr = 0;
1949 }
1950
1951 /* Table Of Contents, 6 bits each */
1952 for (;;) {
1953 pj_uint8_t TOC;
1954 pj_uint8_t F, FT, Q;
1955
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001956 F = (pj_uint8_t)((*r & 0x40) == 0);
1957 FT = (pj_uint8_t)(*r & 0x0F);
1958 Q = (pj_uint8_t)((*r & 0x80) == 0);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001959
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001960 pj_assert(FT <= SID_FT || FT == 14 || FT == 15);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001961 TOC = (pj_uint8_t)((F<<5) | (FT<<1) | Q);
1962
1963 if (w_bitptr == 0) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001964 *w = (pj_uint8_t)(TOC<<2);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001965 w_bitptr = 6;
1966 } else if (w_bitptr == 2) {
1967 *w++ |= TOC;
1968 w_bitptr = 0;
1969 } else if (w_bitptr == 4) {
1970 *w++ |= TOC>>2;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001971 *w = (pj_uint8_t)(TOC<<6);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001972 w_bitptr = 2;
1973 } else if (w_bitptr == 6) {
1974 *w++ |= TOC>>4;
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00001975 *w = (pj_uint8_t)(TOC<<4);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001976 w_bitptr = 4;
1977 }
1978
1979 if (octet_aligned) {
1980 ++w;
1981 w_bitptr = 0;
1982 }
1983
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001984 if (FT > SID_FT)
1985 /* NO DATA */
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001986 r += 1;
1987 else
Nanang Izzuddindf361e02008-08-16 06:46:08 +00001988 r += framelen_tbl[FT] + 1;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00001989
1990 /* Last frame */
1991 if (!F)
1992 break;
1993 }
1994
1995 /* Speech frames */
1996 r = (pj_uint8_t*)pkt + max_pkt_size - *pkt_size;
1997
1998 for (;;) {
1999 pj_uint8_t F, FT;
2000 pj_int8_t amr_bits[477 + 7] = {0};
2001 pj_int8_t *p_amr_bits = &amr_bits[0];
2002 unsigned i;
2003
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002004 F = (pj_uint8_t)((*r & 0x40) == 0);
2005 FT = (pj_uint8_t)(*r & 0x0F);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002006 pj_assert(FT <= SID_FT || FT == 14 || FT == 15);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002007
2008 ++r;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002009 if (FT > SID_FT) {
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002010 if (!F)
2011 break;
2012 continue;
2013 }
2014
2015 /* Unpack bits */
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002016 for(i = 0; i < framelen_tbl[FT]; ++i) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002017 *p_amr_bits++ = (pj_uint8_t)((*r >> 7) & 1);
2018 *p_amr_bits++ = (pj_uint8_t)((*r >> 6) & 1);
2019 *p_amr_bits++ = (pj_uint8_t)((*r >> 5) & 1);
2020 *p_amr_bits++ = (pj_uint8_t)((*r >> 4) & 1);
2021 *p_amr_bits++ = (pj_uint8_t)((*r >> 3) & 1);
2022 *p_amr_bits++ = (pj_uint8_t)((*r >> 2) & 1);
2023 *p_amr_bits++ = (pj_uint8_t)((*r >> 1) & 1);
2024 *p_amr_bits++ = (pj_uint8_t)((*r ) & 1);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002025 ++r;
2026 }
2027
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002028 if (FT < SID_FT) {
2029 /* Speech */
2030 pj_int16_t *order_map_;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002031
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002032 /* Put bits in the packet, sensitivity descending ordered */
2033 order_map_ = order_map[FT];
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002034 if (w_bitptr == 0) *w = 0;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002035 for(i = 0; i < framelenbit_tbl[FT]; ++i) {
2036 pj_uint8_t bit;
2037 bit = amr_bits[order_map_[i]];
2038
2039 if (bit)
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002040 *w |= (1 << (7-w_bitptr));
2041
2042 if (++w_bitptr == 8) {
2043 w_bitptr = 0;
2044 ++w;
2045 *w = 0;
2046 }
2047 }
2048
2049 if (octet_aligned) {
2050 ++w;
2051 w_bitptr = 0;
2052 }
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002053 } else if (FT == SID_FT) {
2054 /* SID */
2055 pj_uint8_t STI = 0;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002056
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002057 amr_bits[35] = (pj_uint8_t)(STI & 1);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002058
2059 if (AMRWB) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002060 amr_bits[36] = (pj_uint8_t)((FT >> 3) & 1);
2061 amr_bits[37] = (pj_uint8_t)((FT >> 2) & 1);
2062 amr_bits[38] = (pj_uint8_t)((FT >> 1) & 1);
2063 amr_bits[39] = (pj_uint8_t)((FT) & 1);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002064 } else {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002065 amr_bits[36] = (pj_uint8_t)((FT >> 2) & 1);
2066 amr_bits[37] = (pj_uint8_t)((FT >> 1) & 1);
2067 amr_bits[38] = (pj_uint8_t)((FT) & 1);
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002068 }
2069
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002070 if (w_bitptr == 0) *w = 0;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002071 for(i = 0; i < framelenbit_tbl[FT]; ++i) {
2072 if (amr_bits[i])
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002073 *w |= (1 << (7-w_bitptr));
2074
2075 if (++w_bitptr == 8) {
2076 w_bitptr = 0;
2077 ++w;
2078 *w = 0;
2079 }
2080 }
2081
2082 if (octet_aligned) {
2083 ++w;
2084 w_bitptr = 0;
2085 }
2086 }
2087
2088 if (!F)
2089 break;
2090 }
2091
2092 *pkt_size = w - (pj_uint8_t*)pkt;
2093 if (w_bitptr)
2094 *pkt_size += 1;
2095
2096 pj_assert(*pkt_size <= max_pkt_size);
2097
2098 return PJ_SUCCESS;
2099}
2100
2101
2102/* Parse AMR payload into frames. Frame.bit_info will contain start_bit and
2103 * AMR frame type, it is mapped as below (bit 0:MSB - bit 31:LSB)
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002104 * - bit 0-16: degraded quality flag (Q)
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002105 * - bit 17-24: start_bit
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002106 * - bit 25-32: frame_type (FT)
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002107 */
2108static pj_status_t parse_amr(ipp_private_t *codec_data, void *pkt,
2109 pj_size_t pkt_size, const pj_timestamp *ts,
2110 unsigned *frame_cnt, pjmedia_frame frames[])
2111{
2112 unsigned cnt = 0;
2113 pj_timestamp ts_ = *ts;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002114 /* Settings */
2115 pj_uint8_t CMR = 15; /* See if remote request code mode */
2116 pj_uint8_t octet_aligned = 0; /* default==0 when SDP not specifying */
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002117 /* Read cursor */
2118 pj_uint8_t r_bitptr = 0;
2119 pj_uint8_t *r = (pj_uint8_t*)pkt;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002120 /* env vars for AMR or AMRWB */
2121 pj_bool_t AMRWB;
2122 pj_uint8_t SID_FT = 8;
2123 pj_uint8_t *framelen_tbl = AMRNB_framelen;
2124 pj_uint16_t *framelenbit_tbl = AMRNB_framelenbits;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002125
2126 PJ_UNUSED_ARG(pkt_size);
2127
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002128 AMRWB = ipp_codec[codec_data->codec_idx].pt == PJMEDIA_RTP_PT_AMRWB;
2129 if (AMRWB) {
2130 SID_FT = 9;
2131 framelen_tbl = AMRWB_framelen;
2132 framelenbit_tbl = AMRWB_framelenbits;
2133 }
2134
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002135 *frame_cnt = 0;
2136
2137 /* Code Mode Request, 4 bits */
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002138 CMR = (pj_uint8_t)((*r >> 4) & 0x0F);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002139 r_bitptr = 4;
2140 if (octet_aligned) {
2141 ++r;
2142 r_bitptr = 0;
2143 }
2144
2145 /* Table Of Contents, 6 bits each */
2146 for (;;) {
2147 pj_uint8_t TOC = 0;
2148 pj_uint8_t F, FT, Q;
2149
2150 if (r_bitptr == 0) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002151 TOC = (pj_uint8_t)(*r >> 2);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002152 r_bitptr = 6;
2153 } else if (r_bitptr == 2) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002154 TOC = (pj_uint8_t)(*r++ & 0x3F);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002155 r_bitptr = 0;
2156 } else if (r_bitptr == 4) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002157 TOC = (pj_uint8_t)((*r++ & 0x0f) << 2);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002158 TOC |= *r >> 6;
2159 r_bitptr = 2;
2160 } else if (r_bitptr == 6) {
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002161 TOC = (pj_uint8_t)((*r++ & 0x03) << 4);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002162 TOC |= *r >> 4;
2163 r_bitptr = 4;
2164 }
2165
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002166 F = (pj_uint8_t)(TOC >> 5);
2167 FT = (pj_uint8_t)((TOC >> 1) & 0x0F);
2168 Q = (pj_uint8_t)(TOC & 1);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002169
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002170 if (FT > SID_FT && FT < 14) {
2171 pj_assert(!"Invalid AMR frametype, stream may be corrupted!");
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002172 break;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002173 }
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002174
2175 if (octet_aligned) {
2176 ++r;
2177 r_bitptr = 0;
2178 }
2179
2180 /* Set frame attributes */
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002181 frames[cnt].bit_info = FT | (Q << 16);
2182 frames[cnt].timestamp = ts_;
2183 frames[cnt].type = PJMEDIA_FRAME_TYPE_AUDIO;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002184
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002185 ts_.u64 += ipp_codec[codec_data->codec_idx].samples_per_frame;
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002186 ++cnt;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002187
2188 if (!F || cnt == *frame_cnt)
2189 break;
2190 }
2191 *frame_cnt = cnt;
2192
2193 cnt = 0;
2194
2195 /* Speech frames */
2196 while (cnt < *frame_cnt) {
2197 unsigned FT;
2198
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002199 FT = frames[cnt].bit_info & 0x0F;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002200
2201 frames[cnt].bit_info |= (r_bitptr << 8);
2202 frames[cnt].buf = r;
2203
2204 if (octet_aligned) {
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002205 r += framelen_tbl[FT];
2206 frames[cnt].size = framelen_tbl[FT];
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002207 } else {
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002208 if (FT == 14 || FT == 15) {
2209 /* NO DATA */
2210 frames[cnt].size = 0;
2211 } else {
2212 unsigned adv_bit;
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002213
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002214 adv_bit = framelenbit_tbl[FT] + r_bitptr;
2215 r += adv_bit >> 3;
2216 r_bitptr = (pj_uint8_t)(adv_bit % 8);
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002217
Nanang Izzuddindf361e02008-08-16 06:46:08 +00002218 frames[cnt].size = adv_bit >> 3;
2219 if (r_bitptr)
2220 ++frames[cnt].size;
2221 }
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002222 }
2223 ++cnt;
2224 }
2225
2226 return PJ_SUCCESS;
2227}
2228
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002229#endif /* PJMEDIA_HAS_INTEL_IPP_CODEC_AMR */
2230
2231
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002232#if defined(_MSC_VER) && PJMEDIA_AUTO_LINK_IPP_LIBS
2233# pragma comment( lib, "ippcore.lib")
2234# pragma comment( lib, "ipps.lib")
2235# pragma comment( lib, "ippsc.lib")
2236# pragma comment( lib, "ippsr.lib")
2237# pragma comment( lib, "usc.lib")
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002238#endif
2239
2240
Benny Prijonoa4e7cdd2008-08-19 15:01:48 +00002241#endif /* PJMEDIA_HAS_INTEL_IPP */
Nanang Izzuddin493a8db2008-08-15 13:17:39 +00002242