Changeset 2247 for pjproject/trunk/pjmedia/src/pjmedia-codec/l16.c
- Timestamp:
- Aug 26, 2008 8:09:03 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia-codec/l16.c
r2039 r2247 21 21 #include <pjmedia/errno.h> 22 22 #include <pjmedia/endpoint.h> 23 #include <pjmedia/plc.h> 24 #include <pjmedia/silencedet.h> 23 25 #include <pj/assert.h> 24 26 #include <pj/pool.h> … … 31 33 */ 32 34 #if defined(PJMEDIA_HAS_L16_CODEC) && PJMEDIA_HAS_L16_CODEC != 0 35 36 #define PLC_DISABLED 0 33 37 34 38 … … 78 82 unsigned output_buf_len, 79 83 struct pjmedia_frame *output); 84 #if !PLC_DISABLED 85 static pj_status_t l16_recover(pjmedia_codec *codec, 86 unsigned output_buf_len, 87 struct pjmedia_frame *output); 88 #endif 80 89 81 90 /* Definition for L16 codec operations. */ … … 88 97 &l16_parse, 89 98 &l16_encode, 90 &l16_decode 99 &l16_decode, 100 &l16_recover 91 101 }; 92 102 … … 108 118 pj_pool_t *pool; 109 119 pj_mutex_t *mutex; 110 pjmedia_codec codec_list;111 120 } l16_factory; 112 121 … … 115 124 struct l16_data 116 125 { 117 unsigned frame_size; /* Frame size, in bytes */ 126 pj_pool_t *pool; 127 unsigned frame_size; /* Frame size, in bytes */ 128 unsigned clock_rate; /* Clock rate */ 129 130 pj_bool_t plc_enabled; 131 #if !PLC_DISABLED 132 pjmedia_plc *plc; 133 #endif 134 pj_bool_t vad_enabled; 135 pjmedia_silence_det *vad; 136 pj_timestamp last_tx; 118 137 }; 119 138 … … 139 158 l16_factory.base.factory_data = NULL; 140 159 l16_factory.endpt = endpt; 141 142 pj_list_init(&l16_factory.codec_list);143 160 144 161 /* Create pool */ … … 253 270 attr->setting.frm_per_pkt = 1; 254 271 255 /* Default all flag bits disabled. */ 272 attr->setting.vad = 1; 273 #if !PLC_DISABLED 274 attr->setting.plc = 1; 275 #endif 256 276 257 277 return PJ_SUCCESS; … … 421 441 struct l16_data *data; 422 442 unsigned ptime; 443 pj_pool_t *pool; 444 445 pj_status_t status; 423 446 424 447 PJ_ASSERT_RETURN(factory==&l16_factory.base, PJ_EINVAL); … … 427 450 pj_mutex_lock(l16_factory.mutex); 428 451 429 /* Allocate new codec if no more is available */ 430 if (pj_list_empty(&l16_factory.codec_list)) { 431 432 codec = PJ_POOL_ALLOC_T(l16_factory.pool, pjmedia_codec); 433 codec->codec_data = pj_pool_alloc(l16_factory.pool, 434 sizeof(struct l16_data)); 435 codec->factory = factory; 436 codec->op = &l16_op; 437 438 } else { 439 codec = l16_factory.codec_list.next; 440 pj_list_erase(codec); 441 } 452 453 pool = pjmedia_endpt_create_pool(l16_factory.endpt, "l16", 4000, 4000); 454 codec = PJ_POOL_ZALLOC_T(pool, pjmedia_codec); 455 codec->codec_data = pj_pool_alloc(pool, sizeof(struct l16_data)); 456 codec->factory = factory; 457 codec->op = &l16_op; 442 458 443 459 /* Init private data */ … … 445 461 data = (struct l16_data*) codec->codec_data; 446 462 data->frame_size = ptime * id->clock_rate * id->channel_cnt * 2 / 1000; 447 448 /* Zero the list, for error detection in l16_dealloc_codec */ 449 codec->next = codec->prev = NULL; 463 data->clock_rate = id->clock_rate; 464 data->pool = pool; 465 466 #if !PLC_DISABLED 467 /* Create PLC */ 468 status = pjmedia_plc_create(pool, id->clock_rate, 469 data->frame_size >> 1, 0, 470 &data->plc); 471 if (status != PJ_SUCCESS) { 472 pj_mutex_unlock(l16_factory.mutex); 473 return status; 474 } 475 #endif 476 477 /* Create silence detector */ 478 status = pjmedia_silence_det_create(pool, id->clock_rate, 479 data->frame_size >> 1, 480 &data->vad); 481 if (status != PJ_SUCCESS) { 482 pj_mutex_unlock(l16_factory.mutex); 483 return status; 484 } 450 485 451 486 *p_codec = codec; … … 460 495 pjmedia_codec *codec ) 461 496 { 462 497 struct l16_data *data; 498 499 PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL); 463 500 PJ_ASSERT_RETURN(factory==&l16_factory.base, PJ_EINVAL); 464 465 /* Check that this node has not been deallocated before */466 pj_assert (codec->next==NULL && codec->prev==NULL);467 if (codec->next!=NULL || codec->prev!=NULL) {468 return PJ_EINVALIDOP;469 }470 501 471 502 /* Lock mutex. */ 472 503 pj_mutex_lock(l16_factory.mutex); 473 504 474 /* Insert at the back of the list */ 475 pj_list_insert_before(&l16_factory.codec_list, codec); 505 /* Just release codec data pool */ 506 data = (struct l16_data*) codec->codec_data; 507 pj_assert(data); 508 pj_pool_release(data->pool); 476 509 477 510 /* Unlock mutex. */ … … 509 542 const pjmedia_codec_param *attr ) 510 543 { 511 /* Don't want to do anything. */ 512 PJ_UNUSED_ARG(codec); 513 PJ_UNUSED_ARG(attr); 514 return PJ_EINVALIDOP; 544 struct l16_data *data = (struct l16_data*) codec->codec_data; 545 546 pj_assert(data != NULL); 547 548 data->vad_enabled = (attr->setting.vad != 0); 549 data->plc_enabled = (attr->setting.plc != 0); 550 551 return PJ_SUCCESS; 515 552 } 516 553 … … 549 586 struct pjmedia_frame *output) 550 587 { 588 struct l16_data *data = (struct l16_data*) codec->codec_data; 551 589 const pj_int16_t *samp = (const pj_int16_t*) input->buf; 552 590 const pj_int16_t *samp_end = samp + input->size/sizeof(pj_int16_t); 553 591 pj_int16_t *samp_out = (pj_int16_t*) output->buf; 554 592 555 556 PJ_UNUSED_ARG(codec); 557 593 pj_assert(data && input && output); 558 594 559 595 /* Check output buffer length */ … … 561 597 return PJMEDIA_CODEC_EFRMTOOSHORT; 562 598 599 /* Detect silence */ 600 if (data->vad_enabled) { 601 pj_bool_t is_silence; 602 pj_int32_t silence_duration; 603 604 silence_duration = pj_timestamp_diff32(&data->last_tx, 605 &input->timestamp); 606 607 is_silence = pjmedia_silence_det_detect(data->vad, 608 (const pj_int16_t*) input->buf, 609 (input->size >> 1), 610 NULL); 611 if (is_silence && 612 PJMEDIA_CODEC_MAX_SILENCE_PERIOD != -1 && 613 silence_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD* 614 (int)data->clock_rate/1000) 615 { 616 output->type = PJMEDIA_FRAME_TYPE_NONE; 617 output->buf = NULL; 618 output->size = 0; 619 output->timestamp = input->timestamp; 620 return PJ_SUCCESS; 621 } else { 622 data->last_tx = input->timestamp; 623 } 624 } 563 625 564 626 /* Encode */ … … 583 645 struct pjmedia_frame *output) 584 646 { 647 struct l16_data *l16_data = (struct l16_data*) codec->codec_data; 585 648 const pj_int16_t *samp = (const pj_int16_t*) input->buf; 586 649 const pj_int16_t *samp_end = samp + input->size/sizeof(pj_int16_t); 587 650 pj_int16_t *samp_out = (pj_int16_t*) output->buf; 588 651 589 590 PJ_ UNUSED_ARG(codec);652 pj_assert(l16_data != NULL); 653 PJ_ASSERT_RETURN(input && output, PJ_EINVAL); 591 654 592 655 … … 608 671 output->size = input->size; 609 672 610 return PJ_SUCCESS; 611 } 612 673 #if !PLC_DISABLED 674 if (l16_data->plc_enabled) 675 pjmedia_plc_save( l16_data->plc, (pj_int16_t*)output->buf); 676 #endif 677 678 return PJ_SUCCESS; 679 } 680 681 #if !PLC_DISABLED 682 /* 683 * Recover lost frame. 684 */ 685 static pj_status_t l16_recover(pjmedia_codec *codec, 686 unsigned output_buf_len, 687 struct pjmedia_frame *output) 688 { 689 struct l16_data *data = (struct l16_data*) codec->codec_data; 690 691 PJ_ASSERT_RETURN(data->plc_enabled, PJ_EINVALIDOP); 692 693 PJ_ASSERT_RETURN(output_buf_len >= data->frame_size, 694 PJMEDIA_CODEC_EPCMTOOSHORT); 695 696 pjmedia_plc_generate(data->plc, (pj_int16_t*)output->buf); 697 output->size = data->frame_size; 698 699 return PJ_SUCCESS; 700 } 701 #endif 613 702 614 703 #endif /* PJMEDIA_HAS_L16_CODEC */
Note: See TracChangeset
for help on using the changeset viewer.