blob: 75ee7ca55a7250a33587b8cddb811de1de045ab2 [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001/* $Id: silk.c 4339 2013-01-31 05:23:46Z ming $ */
2/*
3 * Copyright (C) 2012-2012 Teluu Inc. (http://www.teluu.com)
4 * Contributed by Regis Montoya (aka r3gis - www.r3gis.fr)
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
21#include <pjmedia-codec/silk.h>
22#include <pjmedia/codec.h>
23#include <pjmedia/delaybuf.h>
24#include <pjmedia/endpoint.h>
25#include <pjmedia/errno.h>
26#include <pjmedia/port.h>
27#include <pj/pool.h>
28#include <pj/string.h>
29#include <pj/assert.h>
30#include <pj/log.h>
31
32#if defined(PJMEDIA_HAS_SILK_CODEC) && (PJMEDIA_HAS_SILK_CODEC!=0)
33
34#include "SKP_Silk_SDK_API.h"
35
36#define THIS_FILE "silk.c"
37
38#ifndef PJMEDIA_SILK_DELAY_BUF_OPTIONS
39 #define PJMEDIA_SILK_DELAY_BUF_OPTIONS PJMEDIA_DELAY_BUF_SIMPLE_FIFO
40#endif
41
42#define FRAME_LENGTH_MS 20
43#define SILK_ENC_CTL_PACKET_LOSS_PCT 10
44#define SILK_MIN_BITRATE 5000
45#define CALC_BITRATE_QUALITY(quality, max_br) \
46 (quality * max_br / 10)
47#define CALC_BITRATE(max_br) \
48 CALC_BITRATE_QUALITY(PJMEDIA_CODEC_SILK_DEFAULT_QUALITY, \
49 max_br);
50
51
52/* Prototypes for SILK factory */
53static pj_status_t silk_test_alloc( pjmedia_codec_factory *factory,
54 const pjmedia_codec_info *id );
55static pj_status_t silk_default_attr( pjmedia_codec_factory *factory,
56 const pjmedia_codec_info *id,
57 pjmedia_codec_param *attr );
58static pj_status_t silk_enum_codecs ( pjmedia_codec_factory *factory,
59 unsigned *count,
60 pjmedia_codec_info codecs[]);
61static pj_status_t silk_alloc_codec( pjmedia_codec_factory *factory,
62 const pjmedia_codec_info *id,
63 pjmedia_codec **p_codec);
64static pj_status_t silk_dealloc_codec( pjmedia_codec_factory *factory,
65 pjmedia_codec *codec );
66
67/* Prototypes for SILK implementation. */
68static pj_status_t silk_codec_init( pjmedia_codec *codec,
69 pj_pool_t *pool );
70static pj_status_t silk_codec_open( pjmedia_codec *codec,
71 pjmedia_codec_param *attr );
72static pj_status_t silk_codec_close( pjmedia_codec *codec );
73static pj_status_t silk_codec_modify( pjmedia_codec *codec,
74 const pjmedia_codec_param *attr );
75static pj_status_t silk_codec_parse( pjmedia_codec *codec,
76 void *pkt,
77 pj_size_t pkt_size,
78 const pj_timestamp *timestamp,
79 unsigned *frame_cnt,
80 pjmedia_frame frames[]);
81static pj_status_t silk_codec_encode( pjmedia_codec *codec,
82 const struct pjmedia_frame *input,
83 unsigned output_buf_len,
84 struct pjmedia_frame *output);
85static pj_status_t silk_codec_decode( pjmedia_codec *codec,
86 const struct pjmedia_frame *input,
87 unsigned output_buf_len,
88 struct pjmedia_frame *output);
89static pj_status_t silk_codec_recover( pjmedia_codec *codec,
90 unsigned output_buf_len,
91 struct pjmedia_frame *output);
92
93
94typedef enum
95{
96 PARAM_NB, /* Index for narrowband parameter. */
97 PARAM_MB, /* Index for medium parameter. */
98 PARAM_WB, /* Index for wideband parameter. */
99 PARAM_SWB, /* Index for super-wideband parameter */
100} silk_mode;
101
102
103/* Silk default parameter */
104typedef struct silk_param
105{
106 int enabled; /* Is this mode enabled? */
107 int pt; /* Payload type. */
108 unsigned clock_rate; /* Default sampling rate to be used. */
109 pj_uint16_t ptime; /* packet length (in ms). */
110 pj_uint32_t bitrate; /* Bit rate for current mode. */
111 pj_uint32_t max_bitrate; /* Max bit rate for current mode. */
112 int complexity; /* Complexity mode: 0/lowest to 2. */
113} silk_param;
114
115
116/* Definition for SILK codec operations. */
117static pjmedia_codec_op silk_op =
118{
119 &silk_codec_init,
120 &silk_codec_open,
121 &silk_codec_close,
122 &silk_codec_modify,
123 &silk_codec_parse,
124 &silk_codec_encode,
125 &silk_codec_decode,
126 &silk_codec_recover
127};
128
129/* Definition for SILK codec factory operations. */
130static pjmedia_codec_factory_op silk_factory_op =
131{
132 &silk_test_alloc,
133 &silk_default_attr,
134 &silk_enum_codecs,
135 &silk_alloc_codec,
136 &silk_dealloc_codec,
137 &pjmedia_codec_silk_deinit
138};
139
140
141/* SILK factory private data */
142static struct silk_factory
143{
144 pjmedia_codec_factory base;
145 pjmedia_endpt *endpt;
146 pj_pool_t *pool;
147 pj_mutex_t *mutex;
148 struct silk_param silk_param[4];
149} silk_factory;
150
151
152/* SILK codec private data. */
153typedef struct silk_private
154{
155 silk_mode mode; /**< Silk mode. */
156 pj_pool_t *pool; /**< Pool for each instance. */
157 unsigned samples_per_frame;
158 pj_uint8_t pcm_bytes_per_sample;
159
160 pj_bool_t enc_ready;
161 SKP_SILK_SDK_EncControlStruct enc_ctl;
162 void *enc_st;
163
164 pj_bool_t dec_ready;
165 SKP_SILK_SDK_DecControlStruct dec_ctl;
166 void *dec_st;
167
168 /* Buffer to hold decoded frames. */
169 void *dec_buf[SILK_MAX_FRAMES_PER_PACKET-1];
170 SKP_int16 dec_buf_size[SILK_MAX_FRAMES_PER_PACKET-1];
171 pj_size_t dec_buf_sz;
172 unsigned dec_buf_cnt;
173 pj_uint32_t pkt_info; /**< Packet info for buffered frames. */
174} silk_private;
175
176
177silk_mode silk_get_mode_from_clock_rate(unsigned clock_rate) {
178 if (clock_rate <= silk_factory.silk_param[PARAM_NB].clock_rate) {
179 return PARAM_NB;
180 } else if (clock_rate <= silk_factory.silk_param[PARAM_MB].clock_rate) {
181 return PARAM_MB;
182 } else if (clock_rate <= silk_factory.silk_param[PARAM_WB].clock_rate) {
183 return PARAM_WB;
184 }
185 return PARAM_SWB;
186}
187
188
189PJ_DEF(pj_status_t) pjmedia_codec_silk_init(pjmedia_endpt *endpt)
190{
191 pjmedia_codec_mgr *codec_mgr;
192 silk_param *sp;
193 pj_status_t status;
194
195 if (silk_factory.endpt != NULL) {
196 /* Already initialized. */
197 return PJ_SUCCESS;
198 }
199
200 /* Init factory */
201 pj_bzero(&silk_factory, sizeof(silk_factory));
202 silk_factory.base.op = &silk_factory_op;
203 silk_factory.base.factory_data = NULL;
204 silk_factory.endpt = endpt;
205
206 /* Create pool */
207 silk_factory.pool = pjmedia_endpt_create_pool(endpt, "silk", 4000, 4000);
208 if (!silk_factory.pool)
209 return PJ_ENOMEM;
210
211 /* Create mutex. */
212 status = pj_mutex_create_simple(silk_factory.pool, "silk",
213 &silk_factory.mutex);
214 if (status != PJ_SUCCESS)
215 goto on_error;
216
217 /* Initialize default codec params */
218
219 /* From SILK docs:
220 - SILK bitrate tables:
221 +----------------+---------+-----------+
222 | | fs (Hz) | BR (kbps) |
223 +----------------+---------+-----------+
224 | Narrowband | 8000 | 6 - 20 |
225 | Mediumband | 12000 | 7 - 25 |
226 | Wideband | 16000 | 8 - 30 |
227 | Super Wideband | 24000 | 12 - 40 |
228 +----------------+---------+-----------+
229 - The upper limits of the bit rate ranges in this table are
230 recommended values.
231 */
232
233 sp = &silk_factory.silk_param[PARAM_NB];
234 sp->pt = PJMEDIA_RTP_PT_SILK_NB;
235 sp->clock_rate = 8000;
236 sp->max_bitrate = 22000;
237 sp->bitrate = CALC_BITRATE(sp->max_bitrate);
238 sp->ptime = FRAME_LENGTH_MS;
239 sp->complexity = PJMEDIA_CODEC_SILK_DEFAULT_COMPLEXITY;
240 sp->enabled = 1;
241
242 sp = &silk_factory.silk_param[PARAM_MB];
243 sp->pt = PJMEDIA_RTP_PT_SILK_MB;
244 sp->clock_rate = 12000;
245 sp->max_bitrate = 28000;
246 sp->bitrate = CALC_BITRATE(sp->max_bitrate);
247 sp->ptime = FRAME_LENGTH_MS;
248 sp->complexity = PJMEDIA_CODEC_SILK_DEFAULT_COMPLEXITY;
249 sp->enabled = 0;
250
251 sp = &silk_factory.silk_param[PARAM_WB];
252 sp->pt = PJMEDIA_RTP_PT_SILK_WB;
253 sp->clock_rate = 16000;
254 sp->max_bitrate = 36000;
255 sp->bitrate = CALC_BITRATE(sp->max_bitrate);
256 sp->ptime = FRAME_LENGTH_MS;
257 sp->complexity = PJMEDIA_CODEC_SILK_DEFAULT_COMPLEXITY;
258 sp->enabled = 1;
259
260 sp = &silk_factory.silk_param[PARAM_SWB];
261 sp->pt = PJMEDIA_RTP_PT_SILK_SWB;
262 sp->clock_rate = 24000;
263 sp->max_bitrate = 46000;
264 sp->bitrate = CALC_BITRATE(sp->max_bitrate);
265 sp->ptime = FRAME_LENGTH_MS;
266 sp->complexity = PJMEDIA_CODEC_SILK_DEFAULT_COMPLEXITY;
267 sp->enabled = 0;
268
269
270 /* Get the codec manager. */
271 codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);
272 if (!codec_mgr) {
273 return PJ_EINVALIDOP;
274 }
275
276 /* Register codec factory to endpoint. */
277 status = pjmedia_codec_mgr_register_factory(codec_mgr,
278 &silk_factory.base);
279 if (status != PJ_SUCCESS)
280 return status;
281
282 PJ_LOG(4,(THIS_FILE, "SILK codec version %s initialized",
283 SKP_Silk_SDK_get_version()));
284 return PJ_SUCCESS;
285
286on_error:
287 if (silk_factory.mutex) {
288 pj_mutex_destroy(silk_factory.mutex);
289 silk_factory.mutex = NULL;
290 }
291 if (silk_factory.pool) {
292 pj_pool_release(silk_factory.pool);
293 silk_factory.pool = NULL;
294 }
295
296 return status;
297}
298
299
300/*
301 * Change the configuration setting of the SILK codec for the specified
302 * clock rate.
303 */
304PJ_DEF(pj_status_t) pjmedia_codec_silk_set_config(
305 unsigned clock_rate,
306 const pjmedia_codec_silk_setting *opt)
307{
308 unsigned i;
309
310 /* Look up in factory modes table */
311 for (i = 0; i < sizeof(silk_factory.silk_param)/
312 sizeof(silk_factory.silk_param[0]); ++i)
313 {
314 if (silk_factory.silk_param[i].clock_rate == clock_rate) {
315 int quality = PJMEDIA_CODEC_SILK_DEFAULT_QUALITY;
316 int complexity = PJMEDIA_CODEC_SILK_DEFAULT_COMPLEXITY;
317
318 silk_factory.silk_param[i].enabled = opt->enabled;
319 if (opt->complexity >= 0)
320 complexity = opt->complexity;
321 silk_factory.silk_param[i].complexity = complexity;
322 if (opt->quality >= 0)
323 quality = opt->quality;
324 silk_factory.silk_param[i].bitrate =
325 CALC_BITRATE_QUALITY(quality,
326 silk_factory.silk_param[i].max_bitrate);
327 if (silk_factory.silk_param[i].bitrate < SILK_MIN_BITRATE)
328 silk_factory.silk_param[i].bitrate = SILK_MIN_BITRATE;
329
330 return PJ_SUCCESS;
331 }
332 }
333
334 return PJ_ENOTFOUND;
335}
336
337
338/*
339 * Unregister SILK codec factory from pjmedia endpoint and deinitialize
340 * the SILK codec library.
341 */
342PJ_DEF(pj_status_t) pjmedia_codec_silk_deinit(void)
343{
344 pjmedia_codec_mgr *codec_mgr;
345 pj_status_t status;
346
347 if (silk_factory.endpt == NULL) {
348 /* Not registered. */
349 return PJ_SUCCESS;
350 }
351
352 /* Lock mutex. */
353 pj_mutex_lock(silk_factory.mutex);
354
355 /* Get the codec manager. */
356 codec_mgr = pjmedia_endpt_get_codec_mgr(silk_factory.endpt);
357 if (!codec_mgr) {
358 silk_factory.endpt = NULL;
359 pj_mutex_unlock(silk_factory.mutex);
360 return PJ_EINVALIDOP;
361 }
362
363 /* Unregister silk codec factory. */
364 status = pjmedia_codec_mgr_unregister_factory(codec_mgr,
365 &silk_factory.base);
366 silk_factory.endpt = NULL;
367
368 /* Destroy mutex. */
369 pj_mutex_destroy(silk_factory.mutex);
370 silk_factory.mutex = NULL;
371
372
373 /* Release pool. */
374 pj_pool_release(silk_factory.pool);
375 silk_factory.pool = NULL;
376
377 return status;
378}
379
380
381/*
382 * Check if factory can allocate the specified codec.
383 */
384static pj_status_t silk_test_alloc(pjmedia_codec_factory *factory,
385 const pjmedia_codec_info *info )
386{
387 const pj_str_t silk_tag = {"SILK", 4};
388 unsigned i;
389
390 PJ_UNUSED_ARG(factory);
391 PJ_ASSERT_RETURN(factory==&silk_factory.base, PJ_EINVAL);
392
393 /* Type MUST be audio. */
394 if (info->type != PJMEDIA_TYPE_AUDIO)
395 return PJMEDIA_CODEC_EUNSUP;
396
397 /* Check encoding name. */
398 if (pj_stricmp(&info->encoding_name, &silk_tag) != 0)
399 return PJMEDIA_CODEC_EUNSUP;
400
401 /* Channel count must be one */
402 if (info->channel_cnt != 1)
403 return PJMEDIA_CODEC_EUNSUP;
404
405 /* Check clock-rate */
406 for (i=0; i<PJ_ARRAY_SIZE(silk_factory.silk_param); ++i) {
407 silk_param *sp = &silk_factory.silk_param[i];
408 if (sp->enabled && info->clock_rate == sp->clock_rate)
409 {
410 return PJ_SUCCESS;
411 }
412 }
413 /* Clock rate not supported */
414 return PJMEDIA_CODEC_EUNSUP;
415}
416
417
418/*
419 * Generate default attribute.
420 */
421static pj_status_t silk_default_attr( pjmedia_codec_factory *factory,
422 const pjmedia_codec_info *id,
423 pjmedia_codec_param *attr )
424{
425 silk_param *sp;
426 int i;
427
428 PJ_ASSERT_RETURN(factory==&silk_factory.base, PJ_EINVAL);
429
430 i = silk_get_mode_from_clock_rate(id->clock_rate);
431 pj_assert(i >= PARAM_NB && i <= PARAM_SWB);
432
433 sp = &silk_factory.silk_param[i];
434
435 pj_bzero(attr, sizeof(pjmedia_codec_param));
436 attr->info.channel_cnt = 1;
437 attr->info.clock_rate = sp->clock_rate;
438 attr->info.avg_bps = sp->bitrate;
439 attr->info.max_bps = sp->max_bitrate;
440 attr->info.frm_ptime = sp->ptime;
441 attr->info.pcm_bits_per_sample = 16;
442 attr->info.pt = (pj_uint8_t) sp->pt;
443 attr->setting.frm_per_pkt = 1;
444 attr->setting.vad = 0; /* DTX is not recommended for quality reason */
445 attr->setting.plc = 1;
446
447 i = 0;
448 attr->setting.dec_fmtp.param[i].name = pj_str("useinbandfec");
449 attr->setting.dec_fmtp.param[i++].val = pj_str("0");
450 /*
451 attr->setting.dec_fmtp.param[i].name = pj_str("maxaveragebitrate");
452 attr->setting.dec_fmtp.param[i++].val = pj_str(mode->bitrate_str);
453 */
454 attr->setting.dec_fmtp.cnt = (pj_uint8_t)i;
455
456 return PJ_SUCCESS;
457}
458
459
460/*
461 * Enum codecs supported by this factory.
462 */
463static pj_status_t silk_enum_codecs(pjmedia_codec_factory *factory,
464 unsigned *count,
465 pjmedia_codec_info codecs[])
466{
467 unsigned max;
468 int i;
469
470 PJ_ASSERT_RETURN(factory==&silk_factory.base, PJ_EINVAL);
471 PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL);
472
473 max = *count;
474 *count = 0;
475
476 for (i = 0; i<PJ_ARRAY_SIZE(silk_factory.silk_param) && *count<max; ++i)
477 {
478 silk_param *sp = &silk_factory.silk_param[i];
479
480 if (!sp->enabled)
481 continue;
482
483 pj_bzero(&codecs[*count], sizeof(pjmedia_codec_info));
484 codecs[*count].encoding_name = pj_str("SILK");
485 codecs[*count].pt = sp->pt;
486 codecs[*count].type = PJMEDIA_TYPE_AUDIO;
487 codecs[*count].clock_rate = sp->clock_rate;
488 codecs[*count].channel_cnt = 1;
489
490 ++*count;
491 }
492
493 return PJ_SUCCESS;
494}
495
496
497/*
498 * Allocate a new SILK codec instance.
499 */
500static pj_status_t silk_alloc_codec(pjmedia_codec_factory *factory,
501 const pjmedia_codec_info *id,
502 pjmedia_codec **p_codec)
503{
504 pj_pool_t *pool;
505 pjmedia_codec *codec;
506 silk_private *silk;
507
508 PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL);
509 PJ_ASSERT_RETURN(factory == &silk_factory.base, PJ_EINVAL);
510
511 /* Create pool for codec instance */
512 pool = pjmedia_endpt_create_pool(silk_factory.endpt, "silk", 512, 512);
513
514 /* Allocate codec */
515 codec = PJ_POOL_ZALLOC_T(pool, pjmedia_codec);
516 codec->op = &silk_op;
517 codec->factory = factory;
518 codec->codec_data = PJ_POOL_ZALLOC_T(pool, silk_private);
519 silk = (silk_private*) codec->codec_data;
520 silk->pool = pool;
521 silk->enc_ready = PJ_FALSE;
522 silk->dec_ready = PJ_FALSE;
523 silk->mode = silk_get_mode_from_clock_rate(id->clock_rate);
524
525 *p_codec = codec;
526 return PJ_SUCCESS;
527}
528
529
530/*
531 * Free codec.
532 */
533static pj_status_t silk_dealloc_codec( pjmedia_codec_factory *factory,
534 pjmedia_codec *codec )
535{
536 silk_private *silk;
537
538 PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL);
539 PJ_ASSERT_RETURN(factory == &silk_factory.base, PJ_EINVAL);
540
541 silk = (silk_private*)codec->codec_data;
542
543 /* Close codec, if it's not closed. */
544 if (silk->enc_ready == PJ_TRUE || silk->dec_ready == PJ_TRUE) {
545 silk_codec_close(codec);
546 }
547
548 pj_pool_release(silk->pool);
549
550 return PJ_SUCCESS;
551}
552
553
554/*
555 * Init codec.
556 */
557static pj_status_t silk_codec_init(pjmedia_codec *codec,
558 pj_pool_t *pool )
559{
560 PJ_UNUSED_ARG(codec);
561 PJ_UNUSED_ARG(pool);
562 return PJ_SUCCESS;
563}
564
565
566/*
567 * Open codec.
568 */
569static pj_status_t silk_codec_open(pjmedia_codec *codec,
570 pjmedia_codec_param *attr )
571{
572
573 silk_private *silk;
574 silk_param *sp;
575 SKP_int st_size, err;
576 pj_bool_t enc_use_fec;
577 unsigned enc_bitrate, i;
578
579 PJ_ASSERT_RETURN(codec && attr, PJ_EINVAL);
580
581 silk = (silk_private*)codec->codec_data;
582 sp = &silk_factory.silk_param[silk->mode];
583
584 /* Already opened? */
585 if (silk->enc_ready || silk->dec_ready)
586 return PJ_SUCCESS;
587
588 /* Allocate and initialize encoder */
589 err = SKP_Silk_SDK_Get_Encoder_Size(&st_size);
590 if (err) {
591 PJ_LOG(3,(THIS_FILE, "Failed to get encoder state size (err=%d)",
592 err));
593 return PJMEDIA_CODEC_EFAILED;
594 }
595 silk->enc_st = pj_pool_zalloc(silk->pool, st_size);
596 err = SKP_Silk_SDK_InitEncoder(silk->enc_st, &silk->enc_ctl);
597 if (err) {
598 PJ_LOG(3,(THIS_FILE, "Failed to init encoder (err=%d)", err));
599 return PJMEDIA_CODEC_EFAILED;
600 }
601
602 /* Check fmtp params */
603 enc_use_fec = PJ_TRUE;
604 enc_bitrate = sp->bitrate;
605 for (i = 0; i < attr->setting.enc_fmtp.cnt; ++i) {
606 pjmedia_codec_fmtp *fmtp = &attr->setting.enc_fmtp;
607 const pj_str_t STR_USEINBANDFEC = {"useinbandfec", 12};
608 const pj_str_t STR_MAXAVERAGEBITRATE = {"maxaveragebitrate", 17};
609
610 if (!pj_stricmp(&fmtp->param[i].name, &STR_USEINBANDFEC)) {
611 enc_use_fec = pj_strtoul(&fmtp->param[i].val) != 0;
612 } else if (!pj_stricmp(&fmtp->param[i].name, &STR_MAXAVERAGEBITRATE)) {
613 enc_bitrate = pj_strtoul(&fmtp->param[i].val);
614 if (enc_bitrate > sp->max_bitrate) {
615 enc_bitrate = sp->max_bitrate;
616 }
617 }
618 }
619
620 /* Setup encoder control for encoding process */
621 silk->enc_ready = PJ_TRUE;
622 silk->samples_per_frame = FRAME_LENGTH_MS *
623 attr->info.clock_rate / 1000;
624 silk->pcm_bytes_per_sample = attr->info.pcm_bits_per_sample / 8;
625
626 silk->enc_ctl.API_sampleRate = attr->info.clock_rate;
627 silk->enc_ctl.maxInternalSampleRate = attr->info.clock_rate;
628 silk->enc_ctl.packetSize = attr->setting.frm_per_pkt *
629 silk->samples_per_frame;
630 /* For useInBandFEC setting to be useful, we need to set
631 * packetLossPercentage greater than LBRR_LOSS_THRES (1)
632 */
633 silk->enc_ctl.packetLossPercentage = SILK_ENC_CTL_PACKET_LOSS_PCT;
634 silk->enc_ctl.useInBandFEC = enc_use_fec;
635 silk->enc_ctl.useDTX = attr->setting.vad;
636 silk->enc_ctl.complexity = sp->complexity;
637 silk->enc_ctl.bitRate = enc_bitrate;
638
639
640 /* Allocate and initialize decoder */
641 err = SKP_Silk_SDK_Get_Decoder_Size(&st_size);
642 if (err) {
643 PJ_LOG(3,(THIS_FILE, "Failed to get decoder state size (err=%d)",
644 err));
645 return PJMEDIA_CODEC_EFAILED;
646 }
647 silk->dec_st = pj_pool_zalloc(silk->pool, st_size);
648 err = SKP_Silk_SDK_InitDecoder(silk->dec_st);
649 if (err) {
650 PJ_LOG(3,(THIS_FILE, "Failed to init decoder (err=%d)", err));
651 return PJMEDIA_CODEC_EFAILED;
652 }
653
654 /* Setup decoder control for decoding process */
655 silk->dec_ctl.API_sampleRate = attr->info.clock_rate;
656 silk->dec_ctl.framesPerPacket = 1; /* for proper PLC at start */
657 silk->dec_ready = PJ_TRUE;
658 silk->dec_buf_sz = attr->info.clock_rate * attr->info.channel_cnt *
659 attr->info.frm_ptime / 1000 *
660 silk->pcm_bytes_per_sample;
661
662 /* Inform the stream to prepare a larger buffer since we cannot parse
663 * SILK packets and split it into individual frames.
664 */
665 attr->info.max_rx_frame_size = attr->info.max_bps *
666 attr->info.frm_ptime / 8 / 1000;
667 if ((attr->info.max_bps * attr->info.frm_ptime) % 8000 != 0)
668 {
669 ++attr->info.max_rx_frame_size;
670 }
671 attr->info.max_rx_frame_size *= SILK_MAX_FRAMES_PER_PACKET;
672
673 return PJ_SUCCESS;
674}
675
676
677/*
678 * Close codec.
679 */
680static pj_status_t silk_codec_close( pjmedia_codec *codec )
681{
682 silk_private *silk;
683 silk = (silk_private*)codec->codec_data;
684
685 silk->enc_ready = PJ_FALSE;
686 silk->dec_ready = PJ_FALSE;
687
688 return PJ_SUCCESS;
689}
690
691
692/*
693 * Modify codec settings.
694 */
695static pj_status_t silk_codec_modify(pjmedia_codec *codec,
696 const pjmedia_codec_param *attr )
697{
698 PJ_TODO(implement_silk_codec_modify);
699
700 PJ_UNUSED_ARG(codec);
701 PJ_UNUSED_ARG(attr);
702
703 return PJ_SUCCESS;
704}
705
706
707/*
708 * Encode frame.
709 */
710static pj_status_t silk_codec_encode(pjmedia_codec *codec,
711 const struct pjmedia_frame *input,
712 unsigned output_buf_len,
713 struct pjmedia_frame *output)
714{
715 silk_private *silk;
716 SKP_int err;
717 unsigned nsamples;
718 SKP_int16 out_size;
719
720 PJ_ASSERT_RETURN(codec && input && output_buf_len && output, PJ_EINVAL);
721 silk = (silk_private*)codec->codec_data;
722
723 /* Check frame in size */
724 nsamples = input->size >> 1;
725 PJ_ASSERT_RETURN(nsamples % silk->samples_per_frame == 0,
726 PJMEDIA_CODEC_EPCMFRMINLEN);
727
728 /* Encode */
729 output->size = 0;
730 out_size = (SKP_int16)output_buf_len;
731 err = SKP_Silk_SDK_Encode(silk->enc_st, &silk->enc_ctl,
732 (SKP_int16*)input->buf, nsamples,
733 (SKP_uint8*)output->buf, &out_size);
734 if (err) {
735 PJ_LOG(3, (THIS_FILE, "Failed to encode frame (err=%d)", err));
736 output->type = PJMEDIA_FRAME_TYPE_NONE;
737 if (err == SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT)
738 return PJMEDIA_CODEC_EFRMTOOSHORT;
739 return PJMEDIA_CODEC_EFAILED;
740 }
741
742 output->size = out_size;
743 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
744 output->timestamp = input->timestamp;
745
746 return PJ_SUCCESS;
747}
748
749
750/*
751 * Get frames in the packet.
752 */
753static pj_status_t silk_codec_parse( pjmedia_codec *codec,
754 void *pkt,
755 pj_size_t pkt_size,
756 const pj_timestamp *ts,
757 unsigned *frame_cnt,
758 pjmedia_frame frames[])
759{
760 silk_private *silk;
761 SKP_Silk_TOC_struct toc;
762 unsigned i, count;
763
764 PJ_ASSERT_RETURN(codec && ts && frames && frame_cnt, PJ_EINVAL);
765 silk = (silk_private*)codec->codec_data;
766
767 SKP_Silk_SDK_get_TOC(pkt, pkt_size, &toc);
768 count = toc.framesInPacket;
769 pj_assert(count <= SILK_MAX_FRAMES_PER_PACKET);
770
771 for (i = 0; i < count; i++) {
772 frames[i].type = PJMEDIA_FRAME_TYPE_AUDIO;
773 frames[i].bit_info = (((unsigned)ts->u64 & 0xFFFF) << 16) |
774 (((unsigned)pkt & 0xFF) << 8) |
775 (toc.framesInPacket << 4) | i;
776 frames[i].buf = pkt;
777 frames[i].size = pkt_size;
778 frames[i].timestamp.u64 = ts->u64 + i * silk->samples_per_frame;
779 }
780
781 *frame_cnt = count;
782 return PJ_SUCCESS;
783}
784
785static pj_status_t silk_codec_decode(pjmedia_codec *codec,
786 const struct pjmedia_frame *input,
787 unsigned output_buf_len,
788 struct pjmedia_frame *output)
789{
790 silk_private *silk;
791 SKP_int16 out_size;
792 SKP_Silk_TOC_struct toc;
793 SKP_int err = 0;
794 unsigned pkt_info, frm_info;
795
796 PJ_ASSERT_RETURN(codec && input && output_buf_len && output, PJ_EINVAL);
797 silk = (silk_private*)codec->codec_data;
798 PJ_ASSERT_RETURN(output_buf_len >= silk->dec_buf_sz, PJ_ETOOSMALL);
799
800 SKP_Silk_SDK_get_TOC(input->buf, input->size, &toc);
801 pkt_info = input->bit_info & 0xFFFFFF00;
802 frm_info = input->bit_info & 0xF;
803
804 if (toc.framesInPacket == 0) {
805 /* In SILK ARM version, the table of content can indicate
806 * that the number of frames in the packet is 0.
807 * Try to get the number of frames in packet that we save
808 * in the frame instead.
809 */
810 toc.framesInPacket = (input->bit_info & 0xF0) >> 4;
811 }
812
813 if (toc.framesInPacket == 0) {
814 output->size = 0;
815 } else if (silk->pkt_info != pkt_info || input->bit_info == 0) {
816 unsigned i;
817 SKP_int16 nsamples;
818
819 silk->pkt_info = pkt_info;
820 nsamples = (SKP_int16)silk->dec_buf_sz / silk->pcm_bytes_per_sample;
821
822 if (toc.framesInPacket-1 > (SKP_int)silk->dec_buf_cnt) {
823 /* Grow the buffer */
824 for (i = silk->dec_buf_cnt+1; i < (unsigned)toc.framesInPacket;
825 i++)
826 {
827 silk->dec_buf[i-1] = pj_pool_alloc(silk->pool,
828 silk->dec_buf_sz);
829 }
830 silk->dec_buf_cnt = toc.framesInPacket-1;
831 }
832
833 /* We need to decode all the frames in the packet. */
834 for (i = 0; i < (unsigned)toc.framesInPacket;) {
835 void *buf;
836 SKP_int16 *size;
837
838 if (i == 0 || i == frm_info) {
839 buf = output->buf;
840 size = &out_size;
841 } else {
842 buf = silk->dec_buf[i-1];
843 size = &silk->dec_buf_size[i-1];
844 }
845
846 *size = nsamples;
847 err = SKP_Silk_SDK_Decode(silk->dec_st, &silk->dec_ctl,
848 0, /* Normal frame flag */
849 input->buf, input->size,
850 buf, size);
851 if (err) {
852 PJ_LOG(3, (THIS_FILE, "Failed to decode frame (err=%d)",
853 err));
854 *size = 0;
855 } else {
856 *size = *size * silk->pcm_bytes_per_sample;
857 }
858
859 if (i == frm_info) {
860 output->size = *size;
861 }
862
863 i++;
864 if (!silk->dec_ctl.moreInternalDecoderFrames &&
865 i < (unsigned)toc.framesInPacket)
866 {
867 /* It turns out that the packet does not have
868 * the number of frames as mentioned in the TOC.
869 */
870 for (; i < (unsigned)toc.framesInPacket; i++) {
871 silk->dec_buf_size[i-1] = 0;
872 if (i == frm_info) {
873 output->size = 0;
874 }
875 }
876 }
877 }
878 } else {
879 /* We have already decoded this packet. */
880 if (frm_info == 0 || silk->dec_buf_size[frm_info-1] == 0) {
881 /* The decoding was a failure. */
882 output->size = 0;
883 } else {
884 /* Copy the decoded frame from the buffer. */
885 pj_assert(frm_info-1 < silk->dec_buf_cnt);
886 if (frm_info-1 >= silk->dec_buf_cnt) {
887 output->size = 0;
888 } else {
889 pj_memcpy(output->buf, silk->dec_buf[frm_info-1],
890 silk->dec_buf_size[frm_info-1]);
891 output->size = silk->dec_buf_size[frm_info-1];
892 }
893 }
894 }
895
896 if (output->size == 0) {
897 output->type = PJMEDIA_TYPE_NONE;
898 output->buf = NULL;
899 return PJMEDIA_CODEC_EFAILED;
900 }
901
902 output->type = PJMEDIA_TYPE_AUDIO;
903 output->timestamp = input->timestamp;
904
905 return PJ_SUCCESS;
906}
907
908
909/*
910 * Recover lost frame.
911 */
912static pj_status_t silk_codec_recover(pjmedia_codec *codec,
913 unsigned output_buf_len,
914 struct pjmedia_frame *output)
915{
916 silk_private *silk;
917 SKP_int16 out_size;
918 SKP_int err;
919
920 PJ_ASSERT_RETURN(codec && output_buf_len && output, PJ_EINVAL);
921 silk = (silk_private*)codec->codec_data;
922
923 out_size = (SKP_int16)output_buf_len / silk->pcm_bytes_per_sample;
924 err = SKP_Silk_SDK_Decode(silk->dec_st, &silk->dec_ctl,
925 1, /* Lost frame flag */
926 NULL,
927 0,
928 output->buf,
929 &out_size);
930 if (err) {
931 PJ_LOG(3, (THIS_FILE, "Failed to conceal lost frame (err=%d)", err));
932 output->type = PJMEDIA_FRAME_TYPE_NONE;
933 output->buf = NULL;
934 output->size = 0;
935 return PJMEDIA_CODEC_EFAILED;
936 }
937
938 output->size = out_size * silk->pcm_bytes_per_sample;
939 output->type = PJMEDIA_FRAME_TYPE_AUDIO;
940
941 return PJ_SUCCESS;
942}
943
944#if defined(_MSC_VER)
945# if PJ_DEBUG
946# pragma comment(lib, "SKP_Silk_FLP_Win32_debug.lib")
947# else
948# pragma comment(lib, "SKP_Silk_FLP_Win32_mt.lib")
949# endif
950#endif
951
952
953#endif /* PJMEDIA_HAS_SILK_CODEC */