1
/* $Id: ipp_codecs.c 4002 2012-03-30 08:05:43Z bennylp $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
#include <pjmedia-codec/ipp_codecs.h>
21
#include <pjmedia-codec/amr_sdp_match.h>
22
#include <pjmedia-codec/g7221_sdp_match.h>
23
#include <pjmedia/codec.h>
24
#include <pjmedia/errno.h>
25
#include <pjmedia/endpoint.h>
26
#include <pjmedia/plc.h>
27
#include <pjmedia/port.h>
28
#include <pjmedia/silencedet.h>
29
#include <pj/assert.h>
33
#include <pj/string.h>
38
* Only build this file if PJMEDIA_HAS_INTEL_IPP != 0
40
#if defined(PJMEDIA_HAS_INTEL_IPP) && PJMEDIA_HAS_INTEL_IPP != 0
43
#include <ippversion.h>
45
#define THIS_FILE "ipp_codecs.c"
48
/* Prototypes for IPP codecs factory */
49
static pj_status_t ipp_test_alloc( pjmedia_codec_factory *factory,
50
const pjmedia_codec_info *id );
51
static pj_status_t ipp_default_attr( pjmedia_codec_factory *factory,
52
const pjmedia_codec_info *id,
53
pjmedia_codec_param *attr );
54
static pj_status_t ipp_enum_codecs( pjmedia_codec_factory *factory,
56
pjmedia_codec_info codecs[]);
57
static pj_status_t ipp_alloc_codec( pjmedia_codec_factory *factory,
58
const pjmedia_codec_info *id,
59
pjmedia_codec **p_codec);
60
static pj_status_t ipp_dealloc_codec( pjmedia_codec_factory *factory,
61
pjmedia_codec *codec );
63
/* Prototypes for IPP codecs implementation. */
64
static pj_status_t ipp_codec_init( pjmedia_codec *codec,
66
static pj_status_t ipp_codec_open( pjmedia_codec *codec,
67
pjmedia_codec_param *attr );
68
static pj_status_t ipp_codec_close( pjmedia_codec *codec );
69
static pj_status_t ipp_codec_modify(pjmedia_codec *codec,
70
const pjmedia_codec_param *attr );
71
static pj_status_t ipp_codec_parse( pjmedia_codec *codec,
74
const pj_timestamp *ts,
76
pjmedia_frame frames[]);
77
static pj_status_t ipp_codec_encode( pjmedia_codec *codec,
78
const struct pjmedia_frame *input,
79
unsigned output_buf_len,
80
struct pjmedia_frame *output);
81
static pj_status_t ipp_codec_decode( pjmedia_codec *codec,
82
const struct pjmedia_frame *input,
83
unsigned output_buf_len,
84
struct pjmedia_frame *output);
85
static pj_status_t ipp_codec_recover(pjmedia_codec *codec,
86
unsigned output_buf_len,
87
struct pjmedia_frame *output);
89
/* Definition for IPP codecs operations. */
90
static pjmedia_codec_op ipp_op =
102
/* Definition for IPP codecs factory operations. */
103
static pjmedia_codec_factory_op ipp_factory_op =
110
&pjmedia_codec_ipp_deinit
113
/* IPP codecs factory */
114
static struct ipp_factory {
115
pjmedia_codec_factory base;
116
pjmedia_endpt *endpt;
119
unsigned g7221_pcm_shift;
122
/* IPP codecs private data. */
123
typedef struct ipp_private {
124
int codec_idx; /**< Codec index. */
125
void *codec_setting; /**< Specific codec setting. */
126
pj_pool_t *pool; /**< Pool for each instance. */
128
USC_Handle enc; /**< Encoder state. */
129
USC_Handle dec; /**< Decoder state. */
130
USC_CodecInfo *info; /**< Native codec info. */
131
pj_uint16_t frame_size; /**< Bitstream frame size. */
133
pj_bool_t plc_enabled; /**< PLC enabled flag. */
134
pjmedia_plc *plc; /**< PJMEDIA PLC engine, NULL if
135
codec has internal PLC. */
137
pj_bool_t vad_enabled; /**< VAD enabled flag. */
138
pjmedia_silence_det *vad; /**< PJMEDIA VAD engine, NULL if
139
codec has internal VAD. */
140
pj_timestamp last_tx; /**< Timestamp of last transmit.*/
142
unsigned g7221_pcm_shift; /**< G722.1 PCM level adjustment*/
146
/* USC codec implementations. */
147
extern USC_Fxns USC_G729AFP_Fxns;
148
extern USC_Fxns USC_G729I_Fxns;
149
extern USC_Fxns USC_G723_Fxns;
150
extern USC_Fxns USC_G726_Fxns;
151
extern USC_Fxns USC_G728_Fxns;
152
extern USC_Fxns USC_G722_Fxns;
153
extern USC_Fxns USC_GSMAMR_Fxns;
154
extern USC_Fxns USC_AMRWB_Fxns;
155
extern USC_Fxns USC_AMRWBE_Fxns;
158
/* CUSTOM CALLBACKS */
160
/* This callback is useful for translating RTP frame into USC frame, e.g:
161
* reassigning frame attributes, reorder bitstream. Default behaviour of
162
* the translation is just setting the USC frame buffer & its size as
163
* specified in RTP frame, setting USC frame frametype to 0, setting bitrate
164
* of USC frame to bitrate info of codec_data. Implement this callback when
165
* the default behaviour is unapplicable.
167
typedef void (*predecode_cb)(ipp_private_t *codec_data,
168
const pjmedia_frame *rtp_frame,
169
USC_Bitstream *usc_frame);
171
/* Parse frames from a packet. Default behaviour of frame parsing is
172
* just separating frames based on calculating frame length derived
173
* from bitrate. Implement this callback when the default behaviour is
176
typedef pj_status_t (*parse_cb)(ipp_private_t *codec_data, void *pkt,
177
pj_size_t pkt_size, const pj_timestamp *ts,
178
unsigned *frame_cnt, pjmedia_frame frames[]);
180
/* Pack frames into a packet. Default behaviour of packing frames is
181
* just stacking the frames with octet aligned without adding any
182
* payload header. Implement this callback when the default behaviour is
185
typedef pj_status_t (*pack_cb)(ipp_private_t *codec_data, void *pkt,
186
pj_size_t *pkt_size, pj_size_t max_pkt_size);
190
/* Custom callback implementations. */
191
static void predecode_g723( ipp_private_t *codec_data,
192
const pjmedia_frame *rtp_frame,
193
USC_Bitstream *usc_frame);
194
static pj_status_t parse_g723( ipp_private_t *codec_data, void *pkt,
195
pj_size_t pkt_size, const pj_timestamp *ts,
196
unsigned *frame_cnt, pjmedia_frame frames[]);
198
static void predecode_g729( ipp_private_t *codec_data,
199
const pjmedia_frame *rtp_frame,
200
USC_Bitstream *usc_frame);
202
static void predecode_amr( ipp_private_t *codec_data,
203
const pjmedia_frame *rtp_frame,
204
USC_Bitstream *usc_frame);
205
static pj_status_t parse_amr( ipp_private_t *codec_data, void *pkt,
206
pj_size_t pkt_size, const pj_timestamp *ts,
207
unsigned *frame_cnt, pjmedia_frame frames[]);
208
static pj_status_t pack_amr( ipp_private_t *codec_data, void *pkt,
209
pj_size_t *pkt_size, pj_size_t max_pkt_size);
211
static void predecode_g7221( ipp_private_t *codec_data,
212
const pjmedia_frame *rtp_frame,
213
USC_Bitstream *usc_frame);
214
static pj_status_t pack_g7221( ipp_private_t *codec_data, void *pkt,
215
pj_size_t *pkt_size, pj_size_t max_pkt_size);
217
/* IPP codec implementation descriptions. */
218
static struct ipp_codec {
219
int enabled; /* Is this codec enabled? */
220
const char *name; /* Codec name. */
221
pj_uint8_t pt; /* Payload type. */
222
USC_Fxns *fxns; /* USC callback functions. */
223
unsigned clock_rate; /* Codec's clock rate. */
224
unsigned channel_count; /* Codec's channel count. */
225
unsigned samples_per_frame; /* Codec's samples count. */
227
unsigned def_bitrate; /* Default bitrate of this codec. */
228
unsigned max_bitrate; /* Maximum bitrate of this codec. */
229
pj_uint8_t frm_per_pkt; /* Default num of frames per packet.*/
230
int has_native_vad; /* Codec has internal VAD? */
231
int has_native_plc; /* Codec has internal PLC? */
233
predecode_cb predecode; /* Callback to translate RTP frame
235
parse_cb parse; /* Callback to parse bitstream. */
236
pack_cb pack; /* Callback to pack bitstream. */
238
pjmedia_codec_fmtp dec_fmtp; /* Decoder's fmtp params. */
243
# if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
244
{1, "AMR", PJMEDIA_RTP_PT_AMR, &USC_GSMAMR_Fxns, 8000, 1, 160,
245
7400, 12200, 2, 1, 1,
246
&predecode_amr, &parse_amr, &pack_amr,
247
{1, {{{"octet-align", 11}, {"1", 1}}} }
251
# if PJMEDIA_HAS_INTEL_IPP_CODEC_AMRWB
252
{1, "AMR-WB", PJMEDIA_RTP_PT_AMRWB, &USC_AMRWB_Fxns, 16000, 1, 320,
253
15850, 23850, 2, 1, 1,
254
&predecode_amr, &parse_amr, &pack_amr,
255
{1, {{{"octet-align", 11}, {"1", 1}}} }
259
# if PJMEDIA_HAS_INTEL_IPP_CODEC_G729
260
# if defined(PJ_HAS_FLOATING_POINT) && (PJ_HAS_FLOATING_POINT != 0)
261
{1, "G729", PJMEDIA_RTP_PT_G729, &USC_G729AFP_Fxns, 8000, 1, 80,
262
8000, 11800, 2, 1, 1,
263
&predecode_g729, NULL, NULL
266
{1, "G729", PJMEDIA_RTP_PT_G729, &USC_G729I_Fxns, 8000, 1, 80,
267
8000, 11800, 2, 1, 1,
268
&predecode_g729, NULL, NULL
273
# if PJMEDIA_HAS_INTEL_IPP_CODEC_G723_1
274
/* This is actually G.723.1 */
275
{1, "G723", PJMEDIA_RTP_PT_G723, &USC_G723_Fxns, 8000, 1, 240,
277
&predecode_g723, &parse_g723, NULL
281
# if PJMEDIA_HAS_INTEL_IPP_CODEC_G726
282
{0, "G726-16", PJMEDIA_RTP_PT_G726_16, &USC_G726_Fxns, 8000, 1, 80,
283
16000, 16000, 2, 0, 0,
286
{0, "G726-24", PJMEDIA_RTP_PT_G726_24, &USC_G726_Fxns, 8000, 1, 80,
287
24000, 24000, 2, 0, 0,
290
{1, "G726-32", PJMEDIA_RTP_PT_G726_32, &USC_G726_Fxns, 8000, 1, 80,
291
32000, 32000, 2, 0, 0,
294
{0, "G726-40", PJMEDIA_RTP_PT_G726_40, &USC_G726_Fxns, 8000, 1, 80,
295
40000, 40000, 2, 0, 0,
298
/* Old definition of G726-32 */
299
{1, "G721", PJMEDIA_RTP_PT_G721, &USC_G726_Fxns, 8000, 1, 80,
300
32000, 32000, 2, 0, 0,
305
# if PJMEDIA_HAS_INTEL_IPP_CODEC_G728
306
{1, "G728", PJMEDIA_RTP_PT_G728, &USC_G728_Fxns, 8000, 1, 80,
307
16000, 16000, 2, 0, 1,
312
# if PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1
313
{0, "G7221", PJMEDIA_RTP_PT_G722_1_16, &USC_G722_Fxns, 16000, 1, 320,
314
16000, 16000, 1, 0, 1,
315
predecode_g7221, NULL, pack_g7221,
316
{1, {{{"bitrate", 7}, {"16000", 5}}} }
318
{1, "G7221", PJMEDIA_RTP_PT_G722_1_24, &USC_G722_Fxns, 16000, 1, 320,
319
24000, 24000, 1, 0, 1,
320
predecode_g7221, NULL, pack_g7221,
321
{1, {{{"bitrate", 7}, {"24000", 5}}} }
323
{1, "G7221", PJMEDIA_RTP_PT_G722_1_32, &USC_G722_Fxns, 16000, 1, 320,
324
32000, 32000, 1, 0, 1,
325
predecode_g7221, NULL, pack_g7221,
326
{1, {{{"bitrate", 7}, {"32000", 5}}} }
332
#if PJMEDIA_HAS_INTEL_IPP_CODEC_G729
334
static void predecode_g729( ipp_private_t *codec_data,
335
const pjmedia_frame *rtp_frame,
336
USC_Bitstream *usc_frame)
338
switch (rtp_frame->size) {
341
usc_frame->frametype = 1;
342
usc_frame->bitrate = codec_data->info->params.modes.bitrate;
346
usc_frame->frametype = 2;
347
usc_frame->bitrate = 6400;
351
usc_frame->frametype = 3;
352
usc_frame->bitrate = 8000;
356
usc_frame->frametype = 4;
357
usc_frame->bitrate = 11800;
360
usc_frame->frametype = 0;
361
usc_frame->bitrate = 0;
365
usc_frame->pBuffer = rtp_frame->buf;
366
usc_frame->nbytes = rtp_frame->size;
369
#endif /* PJMEDIA_HAS_INTEL_IPP_CODEC_G729 */
372
#if PJMEDIA_HAS_INTEL_IPP_CODEC_G723_1
374
static void predecode_g723( ipp_private_t *codec_data,
375
const pjmedia_frame *rtp_frame,
376
USC_Bitstream *usc_frame)
379
pj_uint8_t *f = (pj_uint8_t*)rtp_frame->buf;
381
PJ_UNUSED_ARG(codec_data);
383
for (i = 0; i < 2; ++i){
385
tmp = (f[0] >> (i & 0x7)) & 1;
389
usc_frame->pBuffer = rtp_frame->buf;
390
usc_frame->nbytes = rtp_frame->size;
391
usc_frame->bitrate = HDR == 0? 6300 : 5300;
392
usc_frame->frametype = 0;
395
static pj_status_t parse_g723(ipp_private_t *codec_data, void *pkt,
396
pj_size_t pkt_size, const pj_timestamp *ts,
397
unsigned *frame_cnt, pjmedia_frame frames[])
400
pj_uint8_t *f = (pj_uint8_t*)pkt;
402
while (pkt_size && count < *frame_cnt) {
406
for (i = 0; i < 2; ++i){
407
j = (f[0] >> (i & 0x7)) & 1;
420
pj_assert(!"Unknown G723.1 frametype, packet may be corrupted!");
421
return PJMEDIA_CODEC_EINMODE;
424
frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;
425
frames[count].buf = f;
426
frames[count].size = framesize;
427
frames[count].timestamp.u64 = ts->u64 + count *
428
ipp_codec[codec_data->codec_idx].samples_per_frame;
431
pkt_size -= framesize;
440
#endif /* PJMEDIA_HAS_INTEL_IPP_CODEC_G723_1 */
443
#if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR || PJMEDIA_HAS_INTEL_IPP_CODEC_AMRWB
445
#include <pjmedia-codec/amr_helper.h>
447
typedef struct amr_settings_t {
448
pjmedia_codec_amr_pack_setting enc_setting;
449
pjmedia_codec_amr_pack_setting dec_setting;
454
/* Rearrange AMR bitstream and convert RTP frame into USC frame:
455
* - make the start_bit to be 0
456
* - if it is speech frame, reorder bitstream from sensitivity bits order
457
* to encoder bits order.
458
* - set the appropriate value of usc_frame.
460
static void predecode_amr( ipp_private_t *codec_data,
461
const pjmedia_frame *rtp_frame,
462
USC_Bitstream *usc_frame)
465
pjmedia_codec_amr_bit_info *info;
466
pjmedia_codec_amr_pack_setting *setting;
468
setting = &((amr_settings_t*)codec_data->codec_setting)->dec_setting;
471
pjmedia_codec_amr_predecode(rtp_frame, setting, &frame);
472
info = (pjmedia_codec_amr_bit_info*) &frame.bit_info;
474
usc_frame->pBuffer = frame.buf;
475
usc_frame->nbytes = frame.size;
476
if (info->mode != -1) {
477
usc_frame->bitrate = setting->amr_nb?
478
pjmedia_codec_amrnb_bitrates[info->mode]:
479
pjmedia_codec_amrwb_bitrates[info->mode];
481
usc_frame->bitrate = 0;
484
if (frame.size > 5) {
486
if (info->good_quality)
487
usc_frame->frametype = 0;
489
usc_frame->frametype = setting->amr_nb ? 5 : 6;
490
} else if (frame.size == 5) {
492
if (info->good_quality) {
493
usc_frame->frametype = info->STI? 2 : 1;
495
usc_frame->frametype = setting->amr_nb ? 6 : 7;
499
usc_frame->frametype = 3;
503
/* Pack AMR payload */
504
static pj_status_t pack_amr(ipp_private_t *codec_data, void *pkt,
505
pj_size_t *pkt_size, pj_size_t max_pkt_size)
507
enum {MAX_FRAMES_PER_PACKET = PJMEDIA_MAX_FRAME_DURATION_MS / 20};
509
pjmedia_frame frames[MAX_FRAMES_PER_PACKET];
510
unsigned nframes = 0;
511
pjmedia_codec_amr_bit_info *info;
512
pj_uint8_t *r; /* Read cursor */
514
pjmedia_codec_amr_pack_setting *setting;
515
const pj_uint8_t *framelen_tbl;
517
setting = &((amr_settings_t*)codec_data->codec_setting)->enc_setting;
518
framelen_tbl = setting->amr_nb? pjmedia_codec_amrnb_framelen:
519
pjmedia_codec_amrwb_framelen;
521
SID_FT = (pj_uint8_t)(setting->amr_nb? 8 : 9);
523
/* Align pkt buf right */
524
r = (pj_uint8_t*)pkt + max_pkt_size - *pkt_size;
525
pj_memmove(r, pkt, *pkt_size);
532
info_ = *((pj_uint16_t*)r);
533
eof = ((info_ & 0x40) != 0);
535
info = (pjmedia_codec_amr_bit_info*) &frames[nframes].bit_info;
536
pj_bzero(info, sizeof(*info));
537
info->frame_type = (pj_uint8_t)(info_ & 0x0F);
538
info->good_quality = (pj_uint8_t)((info_ & 0x80) == 0);
539
info->mode = (pj_int8_t) ((info_ >> 8) & 0x0F);
540
info->STI = (pj_uint8_t)((info_ >> 5) & 1);
542
frames[nframes].buf = r + 2;
543
frames[nframes].size = info->frame_type <= SID_FT ?
544
framelen_tbl[info->frame_type] : 0;
546
r += frames[nframes].size + 2;
549
if (++nframes >= MAX_FRAMES_PER_PACKET || eof)
554
*pkt_size = max_pkt_size;
555
return pjmedia_codec_amr_pack(frames, nframes, setting, pkt, pkt_size);
559
/* Parse AMR payload into frames. */
560
static pj_status_t parse_amr(ipp_private_t *codec_data, void *pkt,
561
pj_size_t pkt_size, const pj_timestamp *ts,
562
unsigned *frame_cnt, pjmedia_frame frames[])
564
amr_settings_t* s = (amr_settings_t*)codec_data->codec_setting;
565
pjmedia_codec_amr_pack_setting *setting;
569
setting = &s->dec_setting;
571
status = pjmedia_codec_amr_parse(pkt, pkt_size, ts, setting, frames,
573
if (status != PJ_SUCCESS)
576
/* Check Change Mode Request. */
577
if (((setting->amr_nb && cmr <= 7) || (!setting->amr_nb && cmr <= 8)) &&
580
struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
583
codec_data->info->params.modes.bitrate = s->enc_setting.amr_nb?
584
pjmedia_codec_amrnb_bitrates[s->enc_mode] :
585
pjmedia_codec_amrwb_bitrates[s->enc_mode];
586
ippc->fxns->std.Control(&codec_data->info->params.modes,
589
PJ_LOG(4,(THIS_FILE, "AMR%s switched encoding mode to: %d (%dbps)",
590
(s->enc_setting.amr_nb?"":"-WB"),
592
codec_data->info->params.modes.bitrate));
598
#endif /* PJMEDIA_HAS_INTEL_IPP_CODEC_AMR */
601
#if PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1
603
static void predecode_g7221( ipp_private_t *codec_data,
604
const pjmedia_frame *rtp_frame,
605
USC_Bitstream *usc_frame)
607
usc_frame->pBuffer = (char*)rtp_frame->buf;
608
usc_frame->nbytes = rtp_frame->size;
609
usc_frame->frametype = 0;
610
usc_frame->bitrate = codec_data->info->params.modes.bitrate;
612
#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
614
pj_uint16_t *p, *p_end;
616
p = (pj_uint16_t*)rtp_frame->buf;
617
p_end = p + rtp_frame->size/2;
626
static pj_status_t pack_g7221( ipp_private_t *codec_data, void *pkt,
627
pj_size_t *pkt_size, pj_size_t max_pkt_size)
629
PJ_UNUSED_ARG(codec_data);
630
PJ_UNUSED_ARG(max_pkt_size);
632
#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
634
pj_uint16_t *p, *p_end;
636
p = (pj_uint16_t*)pkt;
637
p_end = p + *pkt_size/2;
645
PJ_UNUSED_ARG(pkt_size);
652
#include <pjmedia-codec/g7221.h>
655
PJ_DEF(pj_status_t) pjmedia_codec_g7221_set_pcm_shift(int val)
657
PJ_ASSERT_RETURN(val >= 0, PJ_EINVAL);
659
ipp_factory.g7221_pcm_shift = val;
664
#endif /* PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1 */
667
* Initialize and register IPP codec factory to pjmedia endpoint.
669
PJ_DEF(pj_status_t) pjmedia_codec_ipp_init( pjmedia_endpt *endpt )
671
pjmedia_codec_mgr *codec_mgr;
675
if (ipp_factory.pool != NULL) {
676
/* Already initialized. */
680
/* Create IPP codec factory. */
681
ipp_factory.base.op = &ipp_factory_op;
682
ipp_factory.base.factory_data = NULL;
683
ipp_factory.endpt = endpt;
684
ipp_factory.g7221_pcm_shift = PJMEDIA_G7221_DEFAULT_PCM_SHIFT;
686
ipp_factory.pool = pjmedia_endpt_create_pool(endpt, "IPP codecs", 4000, 4000);
687
if (!ipp_factory.pool)
691
status = pj_mutex_create_simple(ipp_factory.pool, "IPP codecs",
693
if (status != PJ_SUCCESS)
696
/* Get the codec manager. */
697
codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);
699
status = PJ_EINVALIDOP;
703
/* Register format match callback. */
704
#if PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1
705
pj_cstr(&codec_name, "G7221");
706
status = pjmedia_sdp_neg_register_fmt_match_cb(
708
&pjmedia_codec_g7221_match_sdp);
709
if (status != PJ_SUCCESS)
713
#if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
714
pj_cstr(&codec_name, "AMR");
715
status = pjmedia_sdp_neg_register_fmt_match_cb(
717
&pjmedia_codec_amr_match_sdp);
718
if (status != PJ_SUCCESS)
722
#if PJMEDIA_HAS_INTEL_IPP_CODEC_AMRWB
723
pj_cstr(&codec_name, "AMR-WB");
724
status = pjmedia_sdp_neg_register_fmt_match_cb(
726
&pjmedia_codec_amr_match_sdp);
727
if (status != PJ_SUCCESS)
731
/* Suppress compile warning */
732
PJ_UNUSED_ARG(codec_name);
734
/* Register codec factory to endpoint. */
735
status = pjmedia_codec_mgr_register_factory(codec_mgr,
737
if (status != PJ_SUCCESS)
744
pj_pool_release(ipp_factory.pool);
745
ipp_factory.pool = NULL;
750
* Unregister IPP codecs factory from pjmedia endpoint.
752
PJ_DEF(pj_status_t) pjmedia_codec_ipp_deinit(void)
754
pjmedia_codec_mgr *codec_mgr;
757
if (ipp_factory.pool == NULL) {
758
/* Already deinitialized */
762
pj_mutex_lock(ipp_factory.mutex);
764
/* Get the codec manager. */
765
codec_mgr = pjmedia_endpt_get_codec_mgr(ipp_factory.endpt);
767
pj_pool_release(ipp_factory.pool);
768
ipp_factory.pool = NULL;
769
return PJ_EINVALIDOP;
772
/* Unregister IPP codecs factory. */
773
status = pjmedia_codec_mgr_unregister_factory(codec_mgr,
777
pj_mutex_destroy(ipp_factory.mutex);
780
pj_pool_release(ipp_factory.pool);
781
ipp_factory.pool = NULL;
788
* Check if factory can allocate the specified codec.
790
static pj_status_t ipp_test_alloc( pjmedia_codec_factory *factory,
791
const pjmedia_codec_info *info )
795
PJ_UNUSED_ARG(factory);
797
/* Type MUST be audio. */
798
if (info->type != PJMEDIA_TYPE_AUDIO)
799
return PJMEDIA_CODEC_EUNSUP;
801
for (i = 0; i < PJ_ARRAY_SIZE(ipp_codec); ++i) {
802
pj_str_t name = pj_str((char*)ipp_codec[i].name);
803
if ((pj_stricmp(&info->encoding_name, &name) == 0) &&
804
(info->clock_rate == (unsigned)ipp_codec[i].clock_rate) &&
805
(info->channel_cnt == (unsigned)ipp_codec[i].channel_count) &&
806
(ipp_codec[i].enabled))
812
/* Unsupported, or mode is disabled. */
813
return PJMEDIA_CODEC_EUNSUP;
817
* Generate default attribute.
819
static pj_status_t ipp_default_attr (pjmedia_codec_factory *factory,
820
const pjmedia_codec_info *id,
821
pjmedia_codec_param *attr )
825
PJ_ASSERT_RETURN(factory==&ipp_factory.base, PJ_EINVAL);
827
pj_bzero(attr, sizeof(pjmedia_codec_param));
829
for (i = 0; i < PJ_ARRAY_SIZE(ipp_codec); ++i) {
830
pj_str_t name = pj_str((char*)ipp_codec[i].name);
831
if ((pj_stricmp(&id->encoding_name, &name) == 0) &&
832
(id->clock_rate == (unsigned)ipp_codec[i].clock_rate) &&
833
(id->channel_cnt == (unsigned)ipp_codec[i].channel_count) &&
834
(id->pt == (unsigned)ipp_codec[i].pt))
836
attr->info.pt = (pj_uint8_t)id->pt;
837
attr->info.channel_cnt = ipp_codec[i].channel_count;
838
attr->info.clock_rate = ipp_codec[i].clock_rate;
839
attr->info.avg_bps = ipp_codec[i].def_bitrate;
840
attr->info.max_bps = ipp_codec[i].max_bitrate;
841
attr->info.pcm_bits_per_sample = 16;
842
attr->info.frm_ptime = (pj_uint16_t)
843
(ipp_codec[i].samples_per_frame * 1000 /
844
ipp_codec[i].channel_count /
845
ipp_codec[i].clock_rate);
846
attr->setting.frm_per_pkt = ipp_codec[i].frm_per_pkt;
849
attr->setting.plc = 1;
850
attr->setting.penh= 0;
851
attr->setting.vad = 1;
852
attr->setting.cng = attr->setting.vad;
853
attr->setting.dec_fmtp = ipp_codec[i].dec_fmtp;
855
if (attr->setting.vad == 0) {
856
#if PJMEDIA_HAS_INTEL_IPP_CODEC_G729
857
if (id->pt == PJMEDIA_RTP_PT_G729) {
858
/* Signal G729 Annex B is being disabled */
859
attr->setting.dec_fmtp.cnt = 1;
860
pj_strset2(&attr->setting.dec_fmtp.param[0].name, "annexb");
861
pj_strset2(&attr->setting.dec_fmtp.param[0].val, "no");
870
return PJMEDIA_CODEC_EUNSUP;
874
* Enum codecs supported by this factory.
876
static pj_status_t ipp_enum_codecs(pjmedia_codec_factory *factory,
878
pjmedia_codec_info codecs[])
883
PJ_UNUSED_ARG(factory);
884
PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);
888
for (i = 0, *count = 0; i < PJ_ARRAY_SIZE(ipp_codec) && *count < max; ++i)
890
if (!ipp_codec[i].enabled)
893
pj_bzero(&codecs[*count], sizeof(pjmedia_codec_info));
894
codecs[*count].encoding_name = pj_str((char*)ipp_codec[i].name);
895
codecs[*count].pt = ipp_codec[i].pt;
896
codecs[*count].type = PJMEDIA_TYPE_AUDIO;
897
codecs[*count].clock_rate = ipp_codec[i].clock_rate;
898
codecs[*count].channel_cnt = ipp_codec[i].channel_count;
907
* Allocate a new codec instance.
909
static pj_status_t ipp_alloc_codec( pjmedia_codec_factory *factory,
910
const pjmedia_codec_info *id,
911
pjmedia_codec **p_codec)
913
ipp_private_t *codec_data;
914
pjmedia_codec *codec;
919
PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);
920
PJ_ASSERT_RETURN(factory == &ipp_factory.base, PJ_EINVAL);
922
pj_mutex_lock(ipp_factory.mutex);
924
/* Find codec's index */
926
for (i = 0; i < PJ_ARRAY_SIZE(ipp_codec); ++i) {
927
pj_str_t name = pj_str((char*)ipp_codec[i].name);
928
if ((pj_stricmp(&id->encoding_name, &name) == 0) &&
929
(id->clock_rate == (unsigned)ipp_codec[i].clock_rate) &&
930
(id->channel_cnt == (unsigned)ipp_codec[i].channel_count) &&
931
(ipp_codec[i].enabled))
939
return PJMEDIA_CODEC_EFAILED;
942
/* Create pool for codec instance */
943
pool = pjmedia_endpt_create_pool(ipp_factory.endpt, "IPPcodec", 512, 512);
944
codec = PJ_POOL_ZALLOC_T(pool, pjmedia_codec);
945
PJ_ASSERT_RETURN(codec != NULL, PJ_ENOMEM);
947
codec->factory = factory;
948
codec->codec_data = PJ_POOL_ZALLOC_T(pool, ipp_private_t);
949
codec_data = (ipp_private_t*) codec->codec_data;
951
/* Create PLC if codec has no internal PLC */
952
if (!ipp_codec[idx].has_native_plc) {
954
status = pjmedia_plc_create(pool, ipp_codec[idx].clock_rate,
955
ipp_codec[idx].samples_per_frame, 0,
957
if (status != PJ_SUCCESS) {
958
pj_pool_release(pool);
959
pj_mutex_unlock(ipp_factory.mutex);
964
/* Create silence detector if codec has no internal VAD */
965
if (!ipp_codec[idx].has_native_vad) {
967
status = pjmedia_silence_det_create(pool,
968
ipp_codec[idx].clock_rate,
969
ipp_codec[idx].samples_per_frame,
971
if (status != PJ_SUCCESS) {
972
pj_pool_release(pool);
973
pj_mutex_unlock(ipp_factory.mutex);
978
codec_data->pool = pool;
979
codec_data->codec_idx = idx;
981
pj_mutex_unlock(ipp_factory.mutex);
990
static pj_status_t ipp_dealloc_codec( pjmedia_codec_factory *factory,
991
pjmedia_codec *codec )
993
ipp_private_t *codec_data;
995
PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);
996
PJ_ASSERT_RETURN(factory == &ipp_factory.base, PJ_EINVAL);
998
/* Close codec, if it's not closed. */
999
codec_data = (ipp_private_t*) codec->codec_data;
1000
if (codec_data->enc != NULL || codec_data->dec != NULL) {
1001
ipp_codec_close(codec);
1004
pj_pool_release(codec_data->pool);
1012
static pj_status_t ipp_codec_init( pjmedia_codec *codec,
1015
PJ_UNUSED_ARG(codec);
1016
PJ_UNUSED_ARG(pool);
1023
static pj_status_t ipp_codec_open( pjmedia_codec *codec,
1024
pjmedia_codec_param *attr )
1026
ipp_private_t *codec_data = (ipp_private_t*) codec->codec_data;
1027
struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
1031
USC_MemBank *membanks;
1034
pool = codec_data->pool;
1036
/* Get the codec info size */
1037
if (USC_NoError != ippc->fxns->std.GetInfoSize(&info_size)) {
1038
PJ_LOG(1,(THIS_FILE, "Error getting codec info size"));
1041
/* Get the codec info */
1042
codec_data->info = pj_pool_zalloc(pool, info_size);
1043
if (USC_NoError != ippc->fxns->std.GetInfo((USC_Handle)NULL,
1046
PJ_LOG(1,(THIS_FILE, "Error getting codec info"));
1050
/* PREPARING THE ENCODER */
1052
/* Setting the encoder params */
1053
codec_data->info->params.direction = USC_ENCODE;
1054
codec_data->info->params.modes.vad = attr->setting.vad &&
1055
ippc->has_native_vad;
1056
codec_data->info->params.modes.bitrate = attr->info.avg_bps;
1057
codec_data->info->params.law = 0; /* Linear PCM input */
1059
#if PJMEDIA_HAS_INTEL_IPP_CODEC_G729
1060
if (ippc->pt == PJMEDIA_RTP_PT_G729) {
1061
/* Check if G729 Annex B is signaled to be disabled */
1062
for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) {
1063
if (pj_stricmp2(&attr->setting.enc_fmtp.param[i].name, "annexb")==0)
1065
if (pj_stricmp2(&attr->setting.enc_fmtp.param[i].val, "no")==0)
1067
attr->setting.vad = 0;
1068
codec_data->info->params.modes.vad = 0;
1076
/* Get number of memory blocks needed by the encoder */
1077
if (USC_NoError != ippc->fxns->std.NumAlloc(&codec_data->info->params,
1080
PJ_LOG(1,(THIS_FILE, "Error getting no of memory blocks of encoder"));
1084
/* Allocate memory blocks table */
1085
membanks = (USC_MemBank*) pj_pool_zalloc(pool,
1086
sizeof(USC_MemBank) * nb_membanks);
1087
/* Get size of each memory block */
1088
if (USC_NoError != ippc->fxns->std.MemAlloc(&codec_data->info->params,
1091
PJ_LOG(1,(THIS_FILE, "Error getting memory blocks size of encoder"));
1095
/* Allocate memory for each block */
1096
for (i = 0; i < nb_membanks; i++) {
1097
membanks[i].pMem = (char*) pj_pool_zalloc(pool, membanks[i].nbytes);
1100
/* Create encoder instance */
1101
if (USC_NoError != ippc->fxns->std.Init(&codec_data->info->params,
1105
PJ_LOG(1,(THIS_FILE, "Error initializing encoder"));
1109
/* PREPARING THE DECODER */
1111
/* Setting the decoder params */
1112
codec_data->info->params.direction = USC_DECODE;
1114
/* Not sure if VAD affects decoder, just try to be safe */
1115
//codec_data->info->params.modes.vad = ippc->has_native_vad;
1117
/* Get number of memory blocks needed by the decoder */
1118
if (USC_NoError != ippc->fxns->std.NumAlloc(&codec_data->info->params,
1121
PJ_LOG(1,(THIS_FILE, "Error getting no of memory blocks of decoder"));
1125
/* Allocate memory blocks table */
1126
membanks = (USC_MemBank*) pj_pool_zalloc(pool,
1127
sizeof(USC_MemBank) * nb_membanks);
1128
/* Get size of each memory block */
1129
if (USC_NoError != ippc->fxns->std.MemAlloc(&codec_data->info->params,
1132
PJ_LOG(1,(THIS_FILE, "Error getting memory blocks size of decoder"));
1136
/* Allocate memory for each block */
1137
for (i = 0; i < nb_membanks; i++) {
1138
membanks[i].pMem = (char*) pj_pool_zalloc(pool, membanks[i].nbytes);
1141
/* Create decoder instance */
1142
if (USC_NoError != ippc->fxns->std.Init(&codec_data->info->params,
1143
membanks, &codec_data->dec))
1145
PJ_LOG(1,(THIS_FILE, "Error initializing decoder"));
1149
/* Update codec info */
1150
ippc->fxns->std.GetInfo((USC_Handle)codec_data->enc, codec_data->info);
1152
/* Get bitstream size */
1153
i = codec_data->info->params.modes.bitrate * ippc->samples_per_frame;
1154
j = ippc->clock_rate << 3;
1155
codec_data->frame_size = (pj_uint16_t)(i / j);
1156
if (i % j) ++codec_data->frame_size;
1158
codec_data->vad_enabled = (attr->setting.vad != 0);
1159
codec_data->plc_enabled = (attr->setting.plc != 0);
1161
#if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
1162
/* Init AMR settings */
1163
if (ippc->pt == PJMEDIA_RTP_PT_AMR || ippc->pt == PJMEDIA_RTP_PT_AMRWB) {
1165
pj_uint8_t octet_align = 0;
1168
enc_mode = pjmedia_codec_amr_get_mode(
1169
codec_data->info->params.modes.bitrate);
1170
pj_assert(enc_mode >= 0 && enc_mode <= 8);
1172
/* Check AMR specific attributes */
1174
for (i = 0; i < attr->setting.dec_fmtp.cnt; ++i) {
1175
/* octet-align, one of the parameters that must have same value
1176
* in offer & answer (RFC 4867 Section 8.3.1). Just check fmtp
1177
* in the decoder side, since it's value is guaranteed to fulfil
1178
* above requirement (by SDP negotiator).
1180
const pj_str_t STR_FMTP_OCTET_ALIGN = {"octet-align", 11};
1182
if (pj_stricmp(&attr->setting.dec_fmtp.param[i].name,
1183
&STR_FMTP_OCTET_ALIGN) == 0)
1185
octet_align=(pj_uint8_t)
1186
pj_strtoul(&attr->setting.dec_fmtp.param[i].val);
1191
for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) {
1192
/* mode-set, encoding mode is chosen based on local default mode
1194
* - if local default mode is included in the mode-set, use it
1195
* - otherwise, find the closest mode to local default mode;
1196
* if there are two closest modes, prefer to use the higher
1197
* one, e.g: local default mode is 4, the mode-set param
1198
* contains '2,3,5,6', then 5 will be chosen.
1200
const pj_str_t STR_FMTP_MODE_SET = {"mode-set", 8};
1202
if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name,
1203
&STR_FMTP_MODE_SET) == 0)
1207
pj_int8_t diff = 99;
1209
p = pj_strbuf(&attr->setting.enc_fmtp.param[i].val);
1210
l = pj_strlen(&attr->setting.enc_fmtp.param[i].val);
1213
if ((ippc->pt==PJMEDIA_RTP_PT_AMR && *p>='0' && *p<='7') ||
1214
(ippc->pt==PJMEDIA_RTP_PT_AMRWB && *p>='0' && *p<='8'))
1216
pj_int8_t tmp = (pj_int8_t)(*p - '0' - enc_mode);
1218
if (PJ_ABS(diff) > PJ_ABS(tmp) ||
1219
(PJ_ABS(diff) == PJ_ABS(tmp) && tmp > diff))
1222
if (diff == 0) break;
1231
enc_mode = (pj_int8_t)(enc_mode + diff);
1237
/* Initialize AMR specific settings */
1238
s = PJ_POOL_ZALLOC_T(pool, amr_settings_t);
1239
codec_data->codec_setting = s;
1241
s->enc_setting.amr_nb = (pj_uint8_t)(ippc->pt == PJMEDIA_RTP_PT_AMR);
1242
s->enc_setting.octet_aligned = octet_align;
1243
s->enc_setting.reorder = PJ_TRUE;
1244
s->enc_setting.cmr = 15;
1246
s->dec_setting.amr_nb = (pj_uint8_t)(ippc->pt == PJMEDIA_RTP_PT_AMR);
1247
s->dec_setting.octet_aligned = octet_align;
1248
s->dec_setting.reorder = PJ_TRUE;
1250
/* Apply encoder mode/bitrate */
1251
s->enc_mode = enc_mode;
1252
codec_data->info->params.modes.bitrate = s->enc_setting.amr_nb?
1253
pjmedia_codec_amrnb_bitrates[s->enc_mode]:
1254
pjmedia_codec_amrwb_bitrates[s->enc_mode];
1255
ippc->fxns->std.Control(&codec_data->info->params.modes,
1258
PJ_LOG(4,(THIS_FILE, "AMR%s encoding mode: %d (%dbps)",
1259
(s->enc_setting.amr_nb?"":"-WB"),
1261
codec_data->info->params.modes.bitrate));
1263
/* Return back bitrate info to application */
1264
attr->info.avg_bps = codec_data->info->params.modes.bitrate;
1268
#if PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1
1269
if (ippc->pt >= PJMEDIA_RTP_PT_G722_1_16 &&
1270
ippc->pt <= PJMEDIA_RTP_PT_G7221_RSV2)
1272
codec_data->g7221_pcm_shift = ipp_factory.g7221_pcm_shift;
1279
return PJMEDIA_CODEC_EFAILED;
1285
static pj_status_t ipp_codec_close( pjmedia_codec *codec )
1287
PJ_UNUSED_ARG(codec);
1294
* Modify codec settings.
1296
static pj_status_t ipp_codec_modify(pjmedia_codec *codec,
1297
const pjmedia_codec_param *attr )
1299
ipp_private_t *codec_data = (ipp_private_t*) codec->codec_data;
1300
struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
1302
codec_data->vad_enabled = (attr->setting.vad != 0);
1303
codec_data->plc_enabled = (attr->setting.plc != 0);
1305
if (ippc->has_native_vad) {
1308
modes = codec_data->info->params.modes;
1309
modes.vad = codec_data->vad_enabled;
1310
ippc->fxns->std.Control(&modes, codec_data->enc);
1317
* Get frames in the packet.
1319
static pj_status_t ipp_codec_parse( pjmedia_codec *codec,
1322
const pj_timestamp *ts,
1323
unsigned *frame_cnt,
1324
pjmedia_frame frames[])
1326
ipp_private_t *codec_data = (ipp_private_t*) codec->codec_data;
1327
struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
1330
PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);
1332
if (ippc->parse != NULL) {
1333
return ippc->parse(codec_data, pkt, pkt_size, ts, frame_cnt, frames);
1336
while (pkt_size >= codec_data->frame_size && count < *frame_cnt) {
1337
frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;
1338
frames[count].buf = pkt;
1339
frames[count].size = codec_data->frame_size;
1340
frames[count].timestamp.u64 = ts->u64 + count*ippc->samples_per_frame;
1342
pkt = ((char*)pkt) + codec_data->frame_size;
1343
pkt_size -= codec_data->frame_size;
1348
if (pkt_size && count < *frame_cnt) {
1349
frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;
1350
frames[count].buf = pkt;
1351
frames[count].size = pkt_size;
1352
frames[count].timestamp.u64 = ts->u64 + count*ippc->samples_per_frame;
1363
static pj_status_t ipp_codec_encode( pjmedia_codec *codec,
1364
const struct pjmedia_frame *input,
1365
unsigned output_buf_len,
1366
struct pjmedia_frame *output)
1368
ipp_private_t *codec_data = (ipp_private_t*) codec->codec_data;
1369
struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
1370
unsigned samples_per_frame;
1373
pj_int16_t *pcm_in = (pj_int16_t*)input->buf;
1374
pj_uint8_t *bits_out = (pj_uint8_t*) output->buf;
1377
/* Invoke external VAD if codec has no internal VAD */
1378
if (codec_data->vad && codec_data->vad_enabled) {
1379
pj_bool_t is_silence;
1380
pj_int32_t silence_duration;
1382
silence_duration = pj_timestamp_diff32(&codec_data->last_tx,
1385
is_silence = pjmedia_silence_det_detect(codec_data->vad,
1386
(const pj_int16_t*) input->buf,
1390
(PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||
1391
silence_duration < (PJMEDIA_CODEC_MAX_SILENCE_PERIOD *
1392
(int)ippc->clock_rate / 1000)))
1394
output->type = PJMEDIA_FRAME_TYPE_NONE;
1397
output->timestamp = input->timestamp;
1400
codec_data->last_tx = input->timestamp;
1404
nsamples = input->size >> 1;
1405
samples_per_frame = ippc->samples_per_frame;
1408
PJ_ASSERT_RETURN(nsamples % samples_per_frame == 0,
1409
PJMEDIA_CODEC_EPCMFRMINLEN);
1411
/* Encode the frames */
1412
while (nsamples >= samples_per_frame) {
1416
in.bitrate = codec_data->info->params.modes.bitrate;
1417
in.nbytes = samples_per_frame << 1;
1418
in.pBuffer = (char*)pcm_in;
1419
in.pcmType.bitPerSample = codec_data->info->params.pcmType.bitPerSample;
1420
in.pcmType.nChannels = codec_data->info->params.pcmType.nChannels;
1421
in.pcmType.sample_frequency = codec_data->info->params.pcmType.sample_frequency;
1423
out.pBuffer = (char*)bits_out;
1425
#if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
1426
/* For AMR: reserve two octets for AMR frame info */
1427
if (pt == PJMEDIA_RTP_PT_AMR || pt == PJMEDIA_RTP_PT_AMRWB) {
1432
#if PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1
1433
/* For G722.1: adjust the encoder input signal level */
1434
if (pt >= PJMEDIA_RTP_PT_G722_1_16 &&
1435
pt <= PJMEDIA_RTP_PT_G7221_RSV2 &&
1436
codec_data->g7221_pcm_shift)
1439
for (i = 0; i < samples_per_frame; ++i)
1440
pcm_in[i] >>= codec_data->g7221_pcm_shift;
1444
if (USC_NoError != ippc->fxns->Encode(codec_data->enc, &in, &out)) {
1448
#if PJMEDIA_HAS_INTEL_IPP_CODEC_AMR
1449
/* For AMR: put info (frametype, degraded, last frame, mode) in the
1450
* first two octets for payload packing.
1452
if (pt == PJMEDIA_RTP_PT_AMR || pt == PJMEDIA_RTP_PT_AMRWB) {
1453
pj_uint16_t *info = (pj_uint16_t*)bits_out;
1455
/* Two octets for AMR frame info, 0=LSB:
1456
* bit 0-3 : frame type
1458
* bit 6 : last frame flag
1459
* bit 7 : quality flag
1463
if (out.frametype == 0 || out.frametype == 4 ||
1464
(pt == PJMEDIA_RTP_PT_AMR && out.frametype == 5) ||
1465
(pt == PJMEDIA_RTP_PT_AMRWB && out.frametype == 6))
1467
/* Speech frame type */
1468
*info = (char)pjmedia_codec_amr_get_mode(out.bitrate);
1470
if (out.frametype == 5 || out.frametype == 6)
1472
} else if (out.frametype == 1 || out.frametype == 2 ||
1473
(pt == PJMEDIA_RTP_PT_AMR && out.frametype == 6) ||
1474
(pt == PJMEDIA_RTP_PT_AMRWB && out.frametype == 7))
1476
/* SID frame type */
1477
*info = (pj_uint8_t)(pt == PJMEDIA_RTP_PT_AMRWB? 9 : 8);
1479
if (out.frametype == 6 || out.frametype == 7)
1482
if (out.frametype != 1)
1491
*info |= (char)pjmedia_codec_amr_get_mode(out.bitrate) << 8;
1493
/* Last frame flag */
1494
if (nsamples == samples_per_frame)
1499
pcm_in += samples_per_frame;
1500
nsamples -= samples_per_frame;
1502
bits_out += out.nbytes;
1504
#if PJMEDIA_HAS_INTEL_IPP_CODEC_G729
1505
if (pt == PJMEDIA_RTP_PT_G729) {
1506
if (out.frametype == 1) {
1509
} else if (out.frametype == 0) {
1519
if (ippc->pack != NULL) {
1520
ippc->pack(codec_data, output->buf, &tx, output_buf_len);
1523
/* Check if we don't need to transmit the frame (DTX) */
1527
output->timestamp.u64 = input->timestamp.u64;
1528
output->type = PJMEDIA_FRAME_TYPE_NONE;
1533
output->type = PJMEDIA_FRAME_TYPE_AUDIO;
1534
output->timestamp = input->timestamp;
1542
static pj_status_t ipp_codec_decode( pjmedia_codec *codec,
1543
const struct pjmedia_frame *input,
1544
unsigned output_buf_len,
1545
struct pjmedia_frame *output)
1547
ipp_private_t *codec_data = (ipp_private_t*) codec->codec_data;
1548
struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
1549
unsigned samples_per_frame;
1555
samples_per_frame = ippc->samples_per_frame;
1557
PJ_ASSERT_RETURN(output_buf_len >= samples_per_frame << 1,
1558
PJMEDIA_CODEC_EPCMTOOSHORT);
1560
if (input->type == PJMEDIA_FRAME_TYPE_AUDIO) {
1561
if (ippc->predecode) {
1562
ippc->predecode(codec_data, input, &in);
1564
/* Most IPP codecs have frametype==0 for speech frame */
1565
in.pBuffer = (char*)input->buf;
1566
in.nbytes = input->size;
1568
in.bitrate = codec_data->info->params.modes.bitrate;
1571
out.pBuffer = output->buf;
1574
if (input->type != PJMEDIA_FRAME_TYPE_AUDIO ||
1575
USC_NoError != ippc->fxns->Decode(codec_data->dec, &in, &out))
1577
pjmedia_zero_samples((pj_int16_t*)output->buf, samples_per_frame);
1578
output->size = samples_per_frame << 1;
1579
output->timestamp.u64 = input->timestamp.u64;
1580
output->type = PJMEDIA_FRAME_TYPE_AUDIO;
1584
#if PJMEDIA_HAS_INTEL_IPP_CODEC_G726
1585
/* For G.726: amplify decoding result (USC G.726 encoder deamplified it) */
1586
if (pt == PJMEDIA_RTP_PT_G726_16 || pt == PJMEDIA_RTP_PT_G726_24 ||
1587
pt == PJMEDIA_RTP_PT_G726_32 || pt == PJMEDIA_RTP_PT_G726_40 ||
1588
pt == PJMEDIA_RTP_PT_G721)
1591
pj_int16_t *s = (pj_int16_t*)output->buf;
1593
for (i = 0; i < samples_per_frame; ++i)
1598
#if PJMEDIA_HAS_INTEL_IPP_CODEC_G722_1
1599
/* For G722.1: adjust the decoder output signal level */
1600
if (pt >= PJMEDIA_RTP_PT_G722_1_16 &&
1601
pt <= PJMEDIA_RTP_PT_G7221_RSV2 &&
1602
codec_data->g7221_pcm_shift)
1605
pj_int16_t *s = (pj_int16_t*)output->buf;
1607
for (i = 0; i < samples_per_frame; ++i)
1608
s[i] <<= codec_data->g7221_pcm_shift;
1612
output->type = PJMEDIA_FRAME_TYPE_AUDIO;
1613
output->size = samples_per_frame << 1;
1614
output->timestamp.u64 = input->timestamp.u64;
1616
/* Invoke external PLC if codec has no internal PLC */
1617
if (codec_data->plc && codec_data->plc_enabled)
1618
pjmedia_plc_save(codec_data->plc, (pj_int16_t*)output->buf);
1624
* Recover lost frame.
1626
static pj_status_t ipp_codec_recover(pjmedia_codec *codec,
1627
unsigned output_buf_len,
1628
struct pjmedia_frame *output)
1630
ipp_private_t *codec_data = (ipp_private_t*) codec->codec_data;
1631
struct ipp_codec *ippc = &ipp_codec[codec_data->codec_idx];
1632
unsigned samples_per_frame;
1634
PJ_UNUSED_ARG(output_buf_len);
1636
samples_per_frame = ippc->samples_per_frame;
1638
output->type = PJMEDIA_FRAME_TYPE_AUDIO;
1639
output->size = samples_per_frame << 1;
1641
if (codec_data->plc_enabled) {
1642
if (codec_data->plc) {
1643
pjmedia_plc_generate(codec_data->plc, (pj_int16_t*)output->buf);
1646
out.pBuffer = output->buf;
1647
ippc->fxns->Decode(codec_data->dec, NULL, &out);
1650
pjmedia_zero_samples((pj_int16_t*)output->buf, samples_per_frame);
1657
#if defined(_MSC_VER) && PJMEDIA_AUTO_LINK_IPP_LIBS
1658
# pragma comment( lib, "ippcore.lib")
1659
# pragma comment( lib, "ipps.lib")
1660
# pragma comment( lib, "ippsc.lib")
1661
# if defined(IPP_VERSION_MAJOR) && IPP_VERSION_MAJOR<=6
1662
# pragma comment( lib, "ippsr.lib")
1664
//# pragma comment( lib, "ippcorel.lib")
1665
//# pragma comment( lib, "ippsemerged.lib")
1666
//# pragma comment( lib, "ippsmerged.lib")
1667
//# pragma comment( lib, "ippscemerged.lib")
1668
//# pragma comment( lib, "ippscmerged.lib")
1669
//# pragma comment( lib, "ippsremerged.lib")
1670
//# pragma comment( lib, "ippsrmerged.lib")
1671
# if defined(IPP_VERSION_MAJOR) && IPP_VERSION_MAJOR>=6
1672
# pragma comment( lib, "speech.lib")
1674
# pragma comment( lib, "usc.lib")
1679
#endif /* PJMEDIA_HAS_INTEL_IPP */