~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/pjmedia/src/pjmedia-codec/ilbc.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: ilbc.c 3664 2011-07-19 03:42:28Z nanang $ */
 
2
/* 
 
3
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 
4
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 
19
 */
 
20
#include <pjmedia-codec/ilbc.h>
 
21
#include <pjmedia-codec/types.h>
 
22
#include <pjmedia/codec.h>
 
23
#include <pjmedia/errno.h>
 
24
#include <pjmedia/endpoint.h>
 
25
#include <pjmedia/plc.h>
 
26
#include <pjmedia/port.h>
 
27
#include <pjmedia/silencedet.h>
 
28
#include <pj/assert.h>
 
29
#include <pj/log.h>
 
30
#include <pj/pool.h>
 
31
#include <pj/string.h>
 
32
#include <pj/os.h>
 
33
 
 
34
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
 
35
    #include <AudioToolbox/AudioToolbox.h>
 
36
    #define iLBC_Enc_Inst_t AudioConverterRef
 
37
    #define iLBC_Dec_Inst_t AudioConverterRef
 
38
    #define BLOCKL_MAX          1
 
39
#else
 
40
    #include "../../third_party/ilbc/iLBC_encode.h"
 
41
    #include "../../third_party/ilbc/iLBC_decode.h"
 
42
#endif
 
43
 
 
44
/*
 
45
 * Only build this file if PJMEDIA_HAS_ILBC_CODEC != 0
 
46
 */
 
47
#if defined(PJMEDIA_HAS_ILBC_CODEC) && PJMEDIA_HAS_ILBC_CODEC != 0
 
48
 
 
49
 
 
50
#define THIS_FILE       "ilbc.c"
 
51
#define CLOCK_RATE      8000
 
52
#define DEFAULT_MODE    30
 
53
 
 
54
 
 
55
/* Prototypes for iLBC factory */
 
56
static pj_status_t ilbc_test_alloc(pjmedia_codec_factory *factory, 
 
57
                                   const pjmedia_codec_info *id );
 
58
static pj_status_t ilbc_default_attr(pjmedia_codec_factory *factory, 
 
59
                                     const pjmedia_codec_info *id, 
 
60
                                     pjmedia_codec_param *attr );
 
61
static pj_status_t ilbc_enum_codecs(pjmedia_codec_factory *factory, 
 
62
                                    unsigned *count, 
 
63
                                    pjmedia_codec_info codecs[]);
 
64
static pj_status_t ilbc_alloc_codec(pjmedia_codec_factory *factory, 
 
65
                                    const pjmedia_codec_info *id, 
 
66
                                    pjmedia_codec **p_codec);
 
67
static pj_status_t ilbc_dealloc_codec(pjmedia_codec_factory *factory, 
 
68
                                      pjmedia_codec *codec );
 
69
 
 
70
/* Prototypes for iLBC implementation. */
 
71
static pj_status_t  ilbc_codec_init(pjmedia_codec *codec, 
 
72
                                    pj_pool_t *pool );
 
73
static pj_status_t  ilbc_codec_open(pjmedia_codec *codec, 
 
74
                                    pjmedia_codec_param *attr );
 
75
static pj_status_t  ilbc_codec_close(pjmedia_codec *codec );
 
76
static pj_status_t  ilbc_codec_modify(pjmedia_codec *codec, 
 
77
                                      const pjmedia_codec_param *attr );
 
78
static pj_status_t  ilbc_codec_parse(pjmedia_codec *codec,
 
79
                                     void *pkt,
 
80
                                     pj_size_t pkt_size,
 
81
                                     const pj_timestamp *ts,
 
82
                                     unsigned *frame_cnt,
 
83
                                     pjmedia_frame frames[]);
 
84
static pj_status_t  ilbc_codec_encode(pjmedia_codec *codec, 
 
85
                                      const struct pjmedia_frame *input,
 
86
                                      unsigned output_buf_len, 
 
87
                                      struct pjmedia_frame *output);
 
88
static pj_status_t  ilbc_codec_decode(pjmedia_codec *codec, 
 
89
                                      const struct pjmedia_frame *input,
 
90
                                      unsigned output_buf_len, 
 
91
                                      struct pjmedia_frame *output);
 
92
static pj_status_t  ilbc_codec_recover(pjmedia_codec *codec,
 
93
                                       unsigned output_buf_len,
 
94
                                       struct pjmedia_frame *output);
 
95
 
 
96
/* Definition for iLBC codec operations. */
 
97
static pjmedia_codec_op ilbc_op = 
 
98
{
 
99
    &ilbc_codec_init,
 
100
    &ilbc_codec_open,
 
101
    &ilbc_codec_close,
 
102
    &ilbc_codec_modify,
 
103
    &ilbc_codec_parse,
 
104
    &ilbc_codec_encode,
 
105
    &ilbc_codec_decode,
 
106
    &ilbc_codec_recover
 
107
};
 
108
 
 
109
/* Definition for iLBC codec factory operations. */
 
110
static pjmedia_codec_factory_op ilbc_factory_op =
 
111
{
 
112
    &ilbc_test_alloc,
 
113
    &ilbc_default_attr,
 
114
    &ilbc_enum_codecs,
 
115
    &ilbc_alloc_codec,
 
116
    &ilbc_dealloc_codec,
 
117
    &pjmedia_codec_ilbc_deinit
 
118
};
 
119
 
 
120
/* iLBC factory */
 
121
static struct ilbc_factory
 
122
{
 
123
    pjmedia_codec_factory    base;
 
124
    pjmedia_endpt           *endpt;
 
125
 
 
126
    int                      mode;
 
127
    int                      bps;
 
128
} ilbc_factory;
 
129
 
 
130
 
 
131
/* iLBC codec private data. */
 
132
struct ilbc_codec
 
133
{
 
134
    pjmedia_codec        base;
 
135
    pj_pool_t           *pool;
 
136
    char                 obj_name[PJ_MAX_OBJ_NAME];
 
137
    pjmedia_silence_det *vad;
 
138
    pj_bool_t            vad_enabled;
 
139
    pj_bool_t            plc_enabled;
 
140
    pj_timestamp         last_tx;
 
141
 
 
142
 
 
143
    pj_bool_t            enc_ready;
 
144
    iLBC_Enc_Inst_t      enc;
 
145
    unsigned             enc_frame_size;
 
146
    unsigned             enc_samples_per_frame;
 
147
    float                enc_block[BLOCKL_MAX];
 
148
 
 
149
    pj_bool_t            dec_ready;
 
150
    iLBC_Dec_Inst_t      dec;
 
151
    unsigned             dec_frame_size;
 
152
    unsigned             dec_samples_per_frame;
 
153
    float                dec_block[BLOCKL_MAX];
 
154
 
 
155
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
 
156
    unsigned             enc_total_packets;
 
157
    char                 *enc_buffer;
 
158
    unsigned             enc_buffer_offset;
 
159
 
 
160
    unsigned             dec_total_packets;
 
161
    char                 *dec_buffer;
 
162
    unsigned             dec_buffer_offset;
 
163
#endif
 
164
};
 
165
 
 
166
static pj_str_t STR_MODE = {"mode", 4};
 
167
 
 
168
/*
 
169
 * Initialize and register iLBC codec factory to pjmedia endpoint.
 
170
 */
 
171
PJ_DEF(pj_status_t) pjmedia_codec_ilbc_init( pjmedia_endpt *endpt,
 
172
                                             int mode )
 
173
{
 
174
    pjmedia_codec_mgr *codec_mgr;
 
175
    pj_status_t status;
 
176
 
 
177
    PJ_ASSERT_RETURN(endpt != NULL, PJ_EINVAL);
 
178
    PJ_ASSERT_RETURN(mode==0 || mode==20 || mode==30, PJ_EINVAL);
 
179
 
 
180
    /* Create iLBC codec factory. */
 
181
    ilbc_factory.base.op = &ilbc_factory_op;
 
182
    ilbc_factory.base.factory_data = NULL;
 
183
    ilbc_factory.endpt = endpt;
 
184
 
 
185
    if (mode == 0)
 
186
        mode = DEFAULT_MODE;
 
187
 
 
188
    ilbc_factory.mode = mode;
 
189
 
 
190
    if (mode == 20) {
 
191
        ilbc_factory.bps = 15200;       
 
192
    } else {
 
193
        ilbc_factory.bps = 13333;
 
194
    }
 
195
 
 
196
    /* Get the codec manager. */
 
197
    codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);
 
198
    if (!codec_mgr)
 
199
        return PJ_EINVALIDOP;
 
200
 
 
201
    /* Register codec factory to endpoint. */
 
202
    status = pjmedia_codec_mgr_register_factory(codec_mgr, 
 
203
                                                &ilbc_factory.base);
 
204
    if (status != PJ_SUCCESS)
 
205
        return status;
 
206
 
 
207
 
 
208
    /* Done. */
 
209
    return PJ_SUCCESS;
 
210
}
 
211
 
 
212
 
 
213
 
 
214
/*
 
215
 * Unregister iLBC codec factory from pjmedia endpoint and deinitialize
 
216
 * the iLBC codec library.
 
217
 */
 
218
PJ_DEF(pj_status_t) pjmedia_codec_ilbc_deinit(void)
 
219
{
 
220
    pjmedia_codec_mgr *codec_mgr;
 
221
    pj_status_t status;
 
222
 
 
223
 
 
224
    /* Get the codec manager. */
 
225
    codec_mgr = pjmedia_endpt_get_codec_mgr(ilbc_factory.endpt);
 
226
    if (!codec_mgr)
 
227
        return PJ_EINVALIDOP;
 
228
 
 
229
    /* Unregister iLBC codec factory. */
 
230
    status = pjmedia_codec_mgr_unregister_factory(codec_mgr,
 
231
                                                  &ilbc_factory.base);
 
232
    
 
233
    return status;
 
234
}
 
235
 
 
236
/* 
 
237
 * Check if factory can allocate the specified codec. 
 
238
 */
 
239
static pj_status_t ilbc_test_alloc( pjmedia_codec_factory *factory, 
 
240
                                   const pjmedia_codec_info *info )
 
241
{
 
242
    const pj_str_t ilbc_tag = { "iLBC", 4};
 
243
 
 
244
    PJ_UNUSED_ARG(factory);
 
245
    PJ_ASSERT_RETURN(factory==&ilbc_factory.base, PJ_EINVAL);
 
246
 
 
247
 
 
248
    /* Type MUST be audio. */
 
249
    if (info->type != PJMEDIA_TYPE_AUDIO)
 
250
        return PJMEDIA_CODEC_EUNSUP;
 
251
 
 
252
    /* Check encoding name. */
 
253
    if (pj_stricmp(&info->encoding_name, &ilbc_tag) != 0)
 
254
        return PJMEDIA_CODEC_EUNSUP;
 
255
 
 
256
    /* Check clock-rate */
 
257
    if (info->clock_rate != CLOCK_RATE)
 
258
        return PJMEDIA_CODEC_EUNSUP;
 
259
    
 
260
    /* Channel count must be one */
 
261
    if (info->channel_cnt != 1)
 
262
        return PJMEDIA_CODEC_EUNSUP;
 
263
 
 
264
    /* Yes, this should be iLBC! */
 
265
    return PJ_SUCCESS;
 
266
}
 
267
 
 
268
 
 
269
/*
 
270
 * Generate default attribute.
 
271
 */
 
272
static pj_status_t ilbc_default_attr (pjmedia_codec_factory *factory, 
 
273
                                      const pjmedia_codec_info *id, 
 
274
                                      pjmedia_codec_param *attr )
 
275
{
 
276
    PJ_UNUSED_ARG(factory);
 
277
    PJ_ASSERT_RETURN(factory==&ilbc_factory.base, PJ_EINVAL);
 
278
 
 
279
    PJ_UNUSED_ARG(id);
 
280
    PJ_ASSERT_RETURN(pj_stricmp2(&id->encoding_name, "iLBC")==0, PJ_EINVAL);
 
281
 
 
282
    pj_bzero(attr, sizeof(pjmedia_codec_param));
 
283
 
 
284
    attr->info.clock_rate = CLOCK_RATE;
 
285
    attr->info.channel_cnt = 1;
 
286
    attr->info.avg_bps = ilbc_factory.bps;
 
287
    attr->info.max_bps = 15200;
 
288
    attr->info.pcm_bits_per_sample = 16;
 
289
    attr->info.frm_ptime = (short)ilbc_factory.mode;
 
290
    attr->info.pt = PJMEDIA_RTP_PT_ILBC;
 
291
 
 
292
    attr->setting.frm_per_pkt = 1;
 
293
    attr->setting.vad = 1;
 
294
    attr->setting.plc = 1;
 
295
    attr->setting.penh = 1;
 
296
    attr->setting.dec_fmtp.cnt = 1;
 
297
    attr->setting.dec_fmtp.param[0].name = STR_MODE;
 
298
    if (ilbc_factory.mode == 30)
 
299
        attr->setting.dec_fmtp.param[0].val = pj_str("30");
 
300
    else
 
301
        attr->setting.dec_fmtp.param[0].val = pj_str("20");
 
302
 
 
303
    return PJ_SUCCESS;
 
304
}
 
305
 
 
306
/*
 
307
 * Enum codecs supported by this factory (i.e. only iLBC!).
 
308
 */
 
309
static pj_status_t ilbc_enum_codecs(pjmedia_codec_factory *factory, 
 
310
                                    unsigned *count, 
 
311
                                    pjmedia_codec_info codecs[])
 
312
{
 
313
    PJ_UNUSED_ARG(factory);
 
314
    PJ_ASSERT_RETURN(factory==&ilbc_factory.base, PJ_EINVAL);
 
315
 
 
316
    PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);
 
317
 
 
318
    pj_bzero(&codecs[0], sizeof(pjmedia_codec_info));
 
319
 
 
320
    codecs[0].encoding_name = pj_str("iLBC");
 
321
    codecs[0].pt = PJMEDIA_RTP_PT_ILBC;
 
322
    codecs[0].type = PJMEDIA_TYPE_AUDIO;
 
323
    codecs[0].clock_rate = 8000;
 
324
    codecs[0].channel_cnt = 1;
 
325
 
 
326
    *count = 1;
 
327
 
 
328
    return PJ_SUCCESS;
 
329
}
 
330
 
 
331
/*
 
332
 * Allocate a new iLBC codec instance.
 
333
 */
 
334
static pj_status_t ilbc_alloc_codec(pjmedia_codec_factory *factory, 
 
335
                                    const pjmedia_codec_info *id,
 
336
                                    pjmedia_codec **p_codec)
 
337
{
 
338
    pj_pool_t *pool;
 
339
    struct ilbc_codec *codec;
 
340
 
 
341
    PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);
 
342
    PJ_ASSERT_RETURN(factory == &ilbc_factory.base, PJ_EINVAL);
 
343
 
 
344
    pool = pjmedia_endpt_create_pool(ilbc_factory.endpt, "iLBC%p",
 
345
                                     2000, 2000);
 
346
    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
 
347
 
 
348
    codec = PJ_POOL_ZALLOC_T(pool, struct ilbc_codec);
 
349
    codec->base.op = &ilbc_op;
 
350
    codec->base.factory = factory;
 
351
    codec->pool = pool;
 
352
 
 
353
    pj_ansi_snprintf(codec->obj_name,  sizeof(codec->obj_name),
 
354
                     "ilbc%p", codec);
 
355
 
 
356
    *p_codec = &codec->base;
 
357
    return PJ_SUCCESS;
 
358
}
 
359
 
 
360
 
 
361
/*
 
362
 * Free codec.
 
363
 */
 
364
static pj_status_t ilbc_dealloc_codec( pjmedia_codec_factory *factory, 
 
365
                                      pjmedia_codec *codec )
 
366
{
 
367
    struct ilbc_codec *ilbc_codec;
 
368
 
 
369
    PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);
 
370
    PJ_UNUSED_ARG(factory);
 
371
    PJ_ASSERT_RETURN(factory == &ilbc_factory.base, PJ_EINVAL);
 
372
 
 
373
    ilbc_codec = (struct ilbc_codec*) codec;
 
374
 
 
375
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
 
376
    if (ilbc_codec->enc) {
 
377
        AudioConverterDispose(ilbc_codec->enc);
 
378
        ilbc_codec->enc = NULL;
 
379
    }
 
380
    if (ilbc_codec->dec) {
 
381
        AudioConverterDispose(ilbc_codec->dec);
 
382
        ilbc_codec->dec = NULL;
 
383
    }
 
384
#endif
 
385
 
 
386
    pj_pool_release(ilbc_codec->pool);
 
387
 
 
388
    return PJ_SUCCESS;
 
389
}
 
390
 
 
391
/*
 
392
 * Init codec.
 
393
 */
 
394
static pj_status_t ilbc_codec_init(pjmedia_codec *codec, 
 
395
                                   pj_pool_t *pool )
 
396
{
 
397
    PJ_UNUSED_ARG(codec);
 
398
    PJ_UNUSED_ARG(pool);
 
399
    return PJ_SUCCESS;
 
400
}
 
401
 
 
402
/*
 
403
 * Open codec.
 
404
 */
 
405
static pj_status_t ilbc_codec_open(pjmedia_codec *codec, 
 
406
                                   pjmedia_codec_param *attr )
 
407
{
 
408
    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
 
409
    pj_status_t status;
 
410
    unsigned i;
 
411
    pj_uint16_t dec_fmtp_mode = DEFAULT_MODE, 
 
412
                enc_fmtp_mode = DEFAULT_MODE;
 
413
 
 
414
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
 
415
    AudioStreamBasicDescription srcFormat, dstFormat;
 
416
    UInt32 size;
 
417
 
 
418
    srcFormat.mSampleRate       = attr->info.clock_rate;
 
419
    srcFormat.mFormatID         = kAudioFormatLinearPCM;
 
420
    srcFormat.mFormatFlags      = kLinearPCMFormatFlagIsSignedInteger
 
421
                                  | kLinearPCMFormatFlagIsPacked;
 
422
    srcFormat.mBitsPerChannel   = attr->info.pcm_bits_per_sample;
 
423
    srcFormat.mChannelsPerFrame = attr->info.channel_cnt;
 
424
    srcFormat.mBytesPerFrame    = srcFormat.mChannelsPerFrame
 
425
                                  * srcFormat.mBitsPerChannel >> 3;
 
426
    srcFormat.mFramesPerPacket  = 1;
 
427
    srcFormat.mBytesPerPacket   = srcFormat.mBytesPerFrame *
 
428
                                  srcFormat.mFramesPerPacket;
 
429
 
 
430
    memset(&dstFormat, 0, sizeof(dstFormat));
 
431
    dstFormat.mSampleRate       = attr->info.clock_rate;
 
432
    dstFormat.mFormatID         = kAudioFormatiLBC;
 
433
    dstFormat.mChannelsPerFrame = attr->info.channel_cnt;
 
434
#endif
 
435
 
 
436
    pj_assert(ilbc_codec != NULL);
 
437
    pj_assert(ilbc_codec->enc_ready == PJ_FALSE && 
 
438
              ilbc_codec->dec_ready == PJ_FALSE);
 
439
 
 
440
    /* Get decoder mode */
 
441
    for (i = 0; i < attr->setting.dec_fmtp.cnt; ++i) {
 
442
        if (pj_stricmp(&attr->setting.dec_fmtp.param[i].name, &STR_MODE) == 0)
 
443
        {
 
444
            dec_fmtp_mode = (pj_uint16_t)
 
445
                            pj_strtoul(&attr->setting.dec_fmtp.param[i].val);
 
446
            break;
 
447
        }
 
448
    }
 
449
 
 
450
    /* Decoder mode must be set */
 
451
    PJ_ASSERT_RETURN(dec_fmtp_mode == 20 || dec_fmtp_mode == 30, 
 
452
                     PJMEDIA_CODEC_EINMODE);
 
453
 
 
454
    /* Get encoder mode */
 
455
    for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) {
 
456
        if (pj_stricmp(&attr->setting.enc_fmtp.param[i].name, &STR_MODE) == 0)
 
457
        {
 
458
            enc_fmtp_mode = (pj_uint16_t)
 
459
                            pj_strtoul(&attr->setting.enc_fmtp.param[i].val);
 
460
            break;
 
461
        }
 
462
    }
 
463
 
 
464
    PJ_ASSERT_RETURN(enc_fmtp_mode==20 || enc_fmtp_mode==30, 
 
465
                     PJMEDIA_CODEC_EINMODE);
 
466
 
 
467
    /* Both sides of a bi-directional session MUST use the same "mode" value.
 
468
     * In this point, possible values are only 20 or 30, so when encoder and
 
469
     * decoder modes are not same, just use the default mode, it is 30.
 
470
     */
 
471
    if (enc_fmtp_mode != dec_fmtp_mode) {
 
472
        enc_fmtp_mode = dec_fmtp_mode = DEFAULT_MODE;
 
473
        PJ_LOG(4,(ilbc_codec->obj_name, 
 
474
                  "Normalized iLBC encoder and decoder modes to %d", 
 
475
                  DEFAULT_MODE));
 
476
    }
 
477
 
 
478
    /* Update some attributes based on negotiated mode. */
 
479
    attr->info.avg_bps = (dec_fmtp_mode == 30? 13333 : 15200);
 
480
    attr->info.frm_ptime = dec_fmtp_mode;
 
481
 
 
482
    /* Create encoder */
 
483
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
 
484
    dstFormat.mFramesPerPacket  = CLOCK_RATE * enc_fmtp_mode / 1000;
 
485
    dstFormat.mBytesPerPacket   = (enc_fmtp_mode == 20? 38 : 50);
 
486
 
 
487
    /* Use AudioFormat API to fill out the rest of the description */
 
488
    size = sizeof(dstFormat);
 
489
    AudioFormatGetProperty(kAudioFormatProperty_FormatInfo,
 
490
                           0, NULL, &size, &dstFormat);
 
491
 
 
492
    if (AudioConverterNew(&srcFormat, &dstFormat, &ilbc_codec->enc) != noErr)
 
493
        return PJMEDIA_CODEC_EFAILED;
 
494
    ilbc_codec->enc_frame_size = (enc_fmtp_mode == 20? 38 : 50);
 
495
#else
 
496
    ilbc_codec->enc_frame_size = initEncode(&ilbc_codec->enc, enc_fmtp_mode);
 
497
#endif
 
498
    ilbc_codec->enc_samples_per_frame = CLOCK_RATE * enc_fmtp_mode / 1000;
 
499
    ilbc_codec->enc_ready = PJ_TRUE;
 
500
 
 
501
    /* Create decoder */
 
502
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
 
503
    if (AudioConverterNew(&dstFormat, &srcFormat, &ilbc_codec->dec) != noErr)
 
504
        return PJMEDIA_CODEC_EFAILED;
 
505
    ilbc_codec->dec_samples_per_frame = CLOCK_RATE * dec_fmtp_mode / 1000;
 
506
#else
 
507
    ilbc_codec->dec_samples_per_frame = initDecode(&ilbc_codec->dec,
 
508
                                                   dec_fmtp_mode,
 
509
                                                   attr->setting.penh);
 
510
#endif
 
511
    ilbc_codec->dec_frame_size = (dec_fmtp_mode == 20? 38 : 50);
 
512
    ilbc_codec->dec_ready = PJ_TRUE;
 
513
 
 
514
    /* Save plc flags */
 
515
    ilbc_codec->plc_enabled = (attr->setting.plc != 0);
 
516
 
 
517
    /* Create silence detector. */
 
518
    ilbc_codec->vad_enabled = (attr->setting.vad != 0);
 
519
    status = pjmedia_silence_det_create(ilbc_codec->pool, CLOCK_RATE,
 
520
                                        ilbc_codec->enc_samples_per_frame,
 
521
                                        &ilbc_codec->vad);
 
522
    if (status != PJ_SUCCESS)
 
523
        return status;
 
524
 
 
525
    /* Init last_tx (not necessary because of zalloc, but better
 
526
     * be safe in case someone remove zalloc later.
 
527
     */
 
528
    pj_set_timestamp32(&ilbc_codec->last_tx, 0, 0);
 
529
 
 
530
    PJ_LOG(5,(ilbc_codec->obj_name, 
 
531
              "iLBC codec opened, mode=%d", dec_fmtp_mode));
 
532
 
 
533
    return PJ_SUCCESS;
 
534
}
 
535
 
 
536
 
 
537
/*
 
538
 * Close codec.
 
539
 */
 
540
static pj_status_t ilbc_codec_close( pjmedia_codec *codec )
 
541
{
 
542
    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
 
543
 
 
544
    PJ_UNUSED_ARG(codec);
 
545
 
 
546
    PJ_LOG(5,(ilbc_codec->obj_name, "iLBC codec closed"));
 
547
 
 
548
    return PJ_SUCCESS;
 
549
}
 
550
 
 
551
/*
 
552
 * Modify codec settings.
 
553
 */
 
554
static pj_status_t  ilbc_codec_modify(pjmedia_codec *codec, 
 
555
                                      const pjmedia_codec_param *attr )
 
556
{
 
557
    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
 
558
 
 
559
    ilbc_codec->plc_enabled = (attr->setting.plc != 0);
 
560
    ilbc_codec->vad_enabled = (attr->setting.vad != 0);
 
561
 
 
562
    return PJ_SUCCESS;
 
563
}
 
564
 
 
565
/*
 
566
 * Get frames in the packet.
 
567
 */
 
568
static pj_status_t  ilbc_codec_parse( pjmedia_codec *codec,
 
569
                                     void *pkt,
 
570
                                     pj_size_t pkt_size,
 
571
                                     const pj_timestamp *ts,
 
572
                                     unsigned *frame_cnt,
 
573
                                     pjmedia_frame frames[])
 
574
{
 
575
    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
 
576
    unsigned count;
 
577
 
 
578
    PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL);
 
579
 
 
580
    count = 0;
 
581
    while (pkt_size >= ilbc_codec->dec_frame_size && count < *frame_cnt) {
 
582
        frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO;
 
583
        frames[count].buf = pkt;
 
584
        frames[count].size = ilbc_codec->dec_frame_size;
 
585
        frames[count].timestamp.u64 = ts->u64 + count * 
 
586
                                      ilbc_codec->dec_samples_per_frame;
 
587
 
 
588
        pkt = ((char*)pkt) + ilbc_codec->dec_frame_size;
 
589
        pkt_size -= ilbc_codec->dec_frame_size;
 
590
 
 
591
        ++count;
 
592
    }
 
593
 
 
594
    *frame_cnt = count;
 
595
    return PJ_SUCCESS;
 
596
}
 
597
 
 
598
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
 
599
static OSStatus encodeDataProc (
 
600
    AudioConverterRef             inAudioConverter,
 
601
    UInt32                        *ioNumberDataPackets,
 
602
    AudioBufferList               *ioData,
 
603
    AudioStreamPacketDescription  **outDataPacketDescription,
 
604
    void                          *inUserData
 
605
)
 
606
{
 
607
    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)inUserData;
 
608
 
 
609
    /* Initialize in case of failure */
 
610
    ioData->mBuffers[0].mData = NULL;
 
611
    ioData->mBuffers[0].mDataByteSize = 0;
 
612
 
 
613
    if (ilbc_codec->enc_total_packets < *ioNumberDataPackets) {
 
614
        *ioNumberDataPackets = ilbc_codec->enc_total_packets;
 
615
    }
 
616
 
 
617
    if (*ioNumberDataPackets) {
 
618
        ioData->mBuffers[0].mData = ilbc_codec->enc_buffer +
 
619
                                    ilbc_codec->enc_buffer_offset;
 
620
        ioData->mBuffers[0].mDataByteSize = *ioNumberDataPackets *
 
621
                                            ilbc_codec->enc_samples_per_frame
 
622
                                            << 1;
 
623
        ilbc_codec->enc_buffer_offset += ioData->mBuffers[0].mDataByteSize;
 
624
    }
 
625
 
 
626
    ilbc_codec->enc_total_packets -= *ioNumberDataPackets;
 
627
    return noErr;
 
628
}
 
629
 
 
630
static OSStatus decodeDataProc (
 
631
    AudioConverterRef             inAudioConverter,
 
632
    UInt32                        *ioNumberDataPackets,
 
633
    AudioBufferList               *ioData,
 
634
    AudioStreamPacketDescription  **outDataPacketDescription,
 
635
    void                          *inUserData
 
636
)
 
637
{
 
638
    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)inUserData;
 
639
 
 
640
    /* Initialize in case of failure */
 
641
    ioData->mBuffers[0].mData = NULL;
 
642
    ioData->mBuffers[0].mDataByteSize = 0;
 
643
 
 
644
    if (ilbc_codec->dec_total_packets < *ioNumberDataPackets) {
 
645
        *ioNumberDataPackets = ilbc_codec->dec_total_packets;
 
646
    }
 
647
 
 
648
    if (*ioNumberDataPackets) {
 
649
        ioData->mBuffers[0].mData = ilbc_codec->dec_buffer +
 
650
                                    ilbc_codec->dec_buffer_offset;
 
651
        ioData->mBuffers[0].mDataByteSize = *ioNumberDataPackets *
 
652
                                            ilbc_codec->dec_frame_size;
 
653
        ilbc_codec->dec_buffer_offset += ioData->mBuffers[0].mDataByteSize;
 
654
    }
 
655
 
 
656
    ilbc_codec->dec_total_packets -= *ioNumberDataPackets;
 
657
    return noErr;
 
658
}
 
659
#endif
 
660
 
 
661
/*
 
662
 * Encode frame.
 
663
 */
 
664
static pj_status_t ilbc_codec_encode(pjmedia_codec *codec, 
 
665
                                     const struct pjmedia_frame *input,
 
666
                                     unsigned output_buf_len, 
 
667
                                     struct pjmedia_frame *output)
 
668
{
 
669
    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
 
670
    pj_int16_t *pcm_in;
 
671
    unsigned nsamples;
 
672
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
 
673
    UInt32 npackets;
 
674
    OSStatus err;
 
675
    AudioBufferList theABL;
 
676
#endif
 
677
 
 
678
    pj_assert(ilbc_codec && input && output);
 
679
 
 
680
    pcm_in = (pj_int16_t*)input->buf;
 
681
    nsamples = input->size >> 1;
 
682
 
 
683
    PJ_ASSERT_RETURN(nsamples % ilbc_codec->enc_samples_per_frame == 0, 
 
684
                     PJMEDIA_CODEC_EPCMFRMINLEN);
 
685
    PJ_ASSERT_RETURN(output_buf_len >= ilbc_codec->enc_frame_size * nsamples /
 
686
                     ilbc_codec->enc_samples_per_frame,
 
687
                     PJMEDIA_CODEC_EFRMTOOSHORT);
 
688
 
 
689
    /* Detect silence */
 
690
    if (ilbc_codec->vad_enabled) {
 
691
        pj_bool_t is_silence;
 
692
        pj_int32_t silence_period;
 
693
 
 
694
        silence_period = pj_timestamp_diff32(&ilbc_codec->last_tx,
 
695
                                              &input->timestamp);
 
696
 
 
697
        is_silence = pjmedia_silence_det_detect(ilbc_codec->vad, 
 
698
                                                (const pj_int16_t*)input->buf,
 
699
                                                (input->size >> 1),
 
700
                                                NULL);
 
701
        if (is_silence &&
 
702
            (PJMEDIA_CODEC_MAX_SILENCE_PERIOD == -1 ||
 
703
             silence_period < PJMEDIA_CODEC_MAX_SILENCE_PERIOD*8000/1000))
 
704
        {
 
705
            output->type = PJMEDIA_FRAME_TYPE_NONE;
 
706
            output->buf = NULL;
 
707
            output->size = 0;
 
708
            output->timestamp = input->timestamp;
 
709
            return PJ_SUCCESS;
 
710
        } else {
 
711
            ilbc_codec->last_tx = input->timestamp;
 
712
        }
 
713
    }
 
714
 
 
715
    /* Encode */
 
716
    output->size = 0;
 
717
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
 
718
    npackets = nsamples / ilbc_codec->enc_samples_per_frame;
 
719
 
 
720
    theABL.mNumberBuffers = 1;
 
721
    theABL.mBuffers[0].mNumberChannels = 1;
 
722
    theABL.mBuffers[0].mDataByteSize = output_buf_len;
 
723
    theABL.mBuffers[0].mData = output->buf;
 
724
 
 
725
    ilbc_codec->enc_total_packets = npackets;
 
726
    ilbc_codec->enc_buffer = (char *)input->buf;
 
727
    ilbc_codec->enc_buffer_offset = 0;
 
728
 
 
729
    err = AudioConverterFillComplexBuffer(ilbc_codec->enc, encodeDataProc,
 
730
                                          ilbc_codec, &npackets,
 
731
                                          &theABL, NULL);
 
732
    if (err == noErr) {
 
733
        output->size = npackets * ilbc_codec->enc_frame_size;
 
734
    }
 
735
#else
 
736
    while (nsamples >= ilbc_codec->enc_samples_per_frame) {
 
737
        unsigned i;
 
738
        
 
739
        /* Convert to float */
 
740
        for (i=0; i<ilbc_codec->enc_samples_per_frame; ++i) {
 
741
            ilbc_codec->enc_block[i] = (float) (*pcm_in++);
 
742
        }
 
743
 
 
744
        iLBC_encode((unsigned char *)output->buf + output->size, 
 
745
                    ilbc_codec->enc_block, 
 
746
                    &ilbc_codec->enc);
 
747
 
 
748
        output->size += ilbc_codec->enc.no_of_bytes;
 
749
        nsamples -= ilbc_codec->enc_samples_per_frame;
 
750
    }
 
751
#endif
 
752
 
 
753
    output->type = PJMEDIA_FRAME_TYPE_AUDIO;
 
754
    output->timestamp = input->timestamp;
 
755
 
 
756
    return PJ_SUCCESS;
 
757
}
 
758
 
 
759
/*
 
760
 * Decode frame.
 
761
 */
 
762
static pj_status_t ilbc_codec_decode(pjmedia_codec *codec, 
 
763
                                     const struct pjmedia_frame *input,
 
764
                                     unsigned output_buf_len, 
 
765
                                     struct pjmedia_frame *output)
 
766
{
 
767
    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
 
768
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
 
769
    UInt32 npackets;
 
770
    OSStatus err;
 
771
    AudioBufferList theABL;
 
772
#else
 
773
    unsigned i;
 
774
#endif
 
775
 
 
776
    pj_assert(ilbc_codec != NULL);
 
777
    PJ_ASSERT_RETURN(input && output, PJ_EINVAL);
 
778
 
 
779
    if (output_buf_len < (ilbc_codec->dec_samples_per_frame << 1))
 
780
        return PJMEDIA_CODEC_EPCMTOOSHORT;
 
781
 
 
782
    if (input->size != ilbc_codec->dec_frame_size)
 
783
        return PJMEDIA_CODEC_EFRMINLEN;
 
784
 
 
785
    /* Decode to temporary buffer */
 
786
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
 
787
    npackets = input->size / ilbc_codec->dec_frame_size *
 
788
               ilbc_codec->dec_samples_per_frame;
 
789
 
 
790
    theABL.mNumberBuffers = 1;
 
791
    theABL.mBuffers[0].mNumberChannels = 1;
 
792
    theABL.mBuffers[0].mDataByteSize = output_buf_len;
 
793
    theABL.mBuffers[0].mData = output->buf;
 
794
 
 
795
    ilbc_codec->dec_total_packets = npackets;
 
796
    ilbc_codec->dec_buffer = (char *)input->buf;
 
797
    ilbc_codec->dec_buffer_offset = 0;
 
798
 
 
799
    err = AudioConverterFillComplexBuffer(ilbc_codec->dec, decodeDataProc,
 
800
                                          ilbc_codec, &npackets,
 
801
                                          &theABL, NULL);
 
802
    if (err == noErr) {
 
803
        output->size = npackets * (ilbc_codec->dec_samples_per_frame << 1);
 
804
    }
 
805
#else
 
806
    iLBC_decode(ilbc_codec->dec_block, (unsigned char*) input->buf,
 
807
                &ilbc_codec->dec, 1);
 
808
 
 
809
    /* Convert decodec samples from float to short */
 
810
    for (i=0; i<ilbc_codec->dec_samples_per_frame; ++i) {
 
811
        ((short*)output->buf)[i] = (short)ilbc_codec->dec_block[i];
 
812
    }
 
813
    output->size = (ilbc_codec->dec_samples_per_frame << 1);
 
814
#endif
 
815
 
 
816
    output->type = PJMEDIA_FRAME_TYPE_AUDIO;
 
817
    output->timestamp = input->timestamp;
 
818
 
 
819
    return PJ_SUCCESS;
 
820
}
 
821
 
 
822
 
 
823
/*
 
824
 * Recover lost frame.
 
825
 */
 
826
static pj_status_t  ilbc_codec_recover(pjmedia_codec *codec,
 
827
                                      unsigned output_buf_len,
 
828
                                      struct pjmedia_frame *output)
 
829
{
 
830
    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
 
831
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
 
832
    UInt32 npackets;
 
833
    OSStatus err;
 
834
    AudioBufferList theABL;
 
835
#else
 
836
    unsigned i;
 
837
#endif
 
838
 
 
839
    pj_assert(ilbc_codec != NULL);
 
840
    PJ_ASSERT_RETURN(output, PJ_EINVAL);
 
841
 
 
842
    if (output_buf_len < (ilbc_codec->dec_samples_per_frame << 1))
 
843
        return PJMEDIA_CODEC_EPCMTOOSHORT;
 
844
 
 
845
    /* Decode to temporary buffer */
 
846
#if defined(PJMEDIA_ILBC_CODEC_USE_COREAUDIO)&& PJMEDIA_ILBC_CODEC_USE_COREAUDIO
 
847
    npackets = 1;
 
848
 
 
849
    theABL.mNumberBuffers = 1;
 
850
    theABL.mBuffers[0].mNumberChannels = 1;
 
851
    theABL.mBuffers[0].mDataByteSize = output_buf_len;
 
852
    theABL.mBuffers[0].mData = output->buf;
 
853
 
 
854
    ilbc_codec->dec_total_packets = npackets;
 
855
    ilbc_codec->dec_buffer_offset = 0;
 
856
    if (ilbc_codec->dec_buffer) {
 
857
        err = AudioConverterFillComplexBuffer(ilbc_codec->dec, decodeDataProc,
 
858
                                              ilbc_codec, &npackets,
 
859
                                              &theABL, NULL);
 
860
        if (err == noErr) {
 
861
            output->size = npackets *
 
862
                           (ilbc_codec->dec_samples_per_frame << 1);
 
863
        }
 
864
    } else {
 
865
        output->size = npackets * (ilbc_codec->dec_samples_per_frame << 1);
 
866
        pj_bzero(output->buf, output->size);
 
867
    }
 
868
#else
 
869
    iLBC_decode(ilbc_codec->dec_block, NULL, &ilbc_codec->dec, 0);
 
870
 
 
871
    /* Convert decodec samples from float to short */
 
872
    for (i=0; i<ilbc_codec->dec_samples_per_frame; ++i) {
 
873
        ((short*)output->buf)[i] = (short)ilbc_codec->dec_block[i];
 
874
    }
 
875
    output->size = (ilbc_codec->dec_samples_per_frame << 1);
 
876
#endif
 
877
    output->type = PJMEDIA_FRAME_TYPE_AUDIO;
 
878
 
 
879
    return PJ_SUCCESS;
 
880
}
 
881
 
 
882
 
 
883
#endif  /* PJMEDIA_HAS_ILBC_CODEC */