| 149 | | /* Set callbacks */ |
|---|
| 150 | | p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **)) |
|---|
| 151 | | DecodeBlock; |
|---|
| | 154 | /* |
|---|
| | 155 | Set callbacks |
|---|
| | 156 | If the codec is spxr then this decoder is |
|---|
| | 157 | being invoked on a Speex stream arriving via RTP. |
|---|
| | 158 | A special decoder callback is used. |
|---|
| | 159 | */ |
|---|
| | 160 | if (p_dec->fmt_in.i_codec == VLC_FOURCC('s', 'p', 'x', 'r')) |
|---|
| | 161 | { |
|---|
| | 162 | msg_Dbg( p_dec, "Using RTP version of Speex decoder @ rate %d.", |
|---|
| | 163 | p_dec->fmt_in.audio.i_rate ); |
|---|
| | 164 | p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **)) |
|---|
| | 165 | DecodeRtpSpeexPacket; |
|---|
| | 166 | } |
|---|
| | 167 | else |
|---|
| | 168 | { |
|---|
| | 169 | p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **)) |
|---|
| | 170 | DecodeBlock; |
|---|
| | 171 | } |
|---|
| 434 | | return SendPacket( p_dec, p_oggpacket, p_block ); |
|---|
| | 452 | if ( p_sys->p_header->frames_per_packet > 1 ) |
|---|
| | 453 | { |
|---|
| | 454 | short *p_frame_holder = NULL; |
|---|
| | 455 | int i_bits_before = 0, i_bits_after = 0, i_bytes_in_speex_frame = 0, |
|---|
| | 456 | i_pcm_output_size = 0, i_bits_in_speex_frame = 0; |
|---|
| | 457 | block_t *p_new_block = NULL; |
|---|
| | 458 | |
|---|
| | 459 | i_pcm_output_size = p_sys->p_header->frame_size; |
|---|
| | 460 | p_frame_holder = (short*)malloc( sizeof(short)*i_pcm_output_size ); |
|---|
| | 461 | |
|---|
| | 462 | speex_bits_read_from( &p_sys->bits, (char*)p_oggpacket->packet, |
|---|
| | 463 | p_oggpacket->bytes); |
|---|
| | 464 | i_bits_before = speex_bits_remaining( &p_sys->bits ); |
|---|
| | 465 | speex_decode_int(p_sys->p_state, &p_sys->bits, p_frame_holder); |
|---|
| | 466 | i_bits_after = speex_bits_remaining( &p_sys->bits ); |
|---|
| | 467 | |
|---|
| | 468 | i_bits_in_speex_frame = i_bits_before - i_bits_after; |
|---|
| | 469 | i_bytes_in_speex_frame = ( i_bits_in_speex_frame + |
|---|
| | 470 | (8 - (i_bits_in_speex_frame % 8)) ) |
|---|
| | 471 | / 8; |
|---|
| | 472 | |
|---|
| | 473 | p_new_block = block_New( p_dec, i_bytes_in_speex_frame ); |
|---|
| | 474 | memset( p_new_block->p_buffer, 0xff, i_bytes_in_speex_frame ); |
|---|
| | 475 | |
|---|
| | 476 | /* |
|---|
| | 477 | * Copy the first frame in this packet to a new packet. |
|---|
| | 478 | */ |
|---|
| | 479 | speex_bits_rewind( &p_sys->bits ); |
|---|
| | 480 | speex_bits_write( &p_sys->bits, |
|---|
| | 481 | p_new_block->p_buffer, |
|---|
| | 482 | i_bytes_in_speex_frame ); |
|---|
| | 483 | |
|---|
| | 484 | /* |
|---|
| | 485 | * Move the remaining part of the original packet (subsequent |
|---|
| | 486 | * frames, if there are any) into the beginning |
|---|
| | 487 | * of the original packet so |
|---|
| | 488 | * they are preserved following the realloc. |
|---|
| | 489 | * Note: Any bits that |
|---|
| | 490 | * remain in the initial packet |
|---|
| | 491 | * are "filler" if they do not constitute |
|---|
| | 492 | * an entire byte. |
|---|
| | 493 | */ |
|---|
| | 494 | if ( i_bits_after > 7 ) |
|---|
| | 495 | { |
|---|
| | 496 | /* round-down since we rounded-up earlier (to include |
|---|
| | 497 | * the speex terminator code. |
|---|
| | 498 | */ |
|---|
| | 499 | i_bytes_in_speex_frame--; |
|---|
| | 500 | speex_bits_write( &p_sys->bits, |
|---|
| | 501 | p_block->p_buffer, |
|---|
| | 502 | p_block->i_buffer - i_bytes_in_speex_frame ); |
|---|
| | 503 | p_block = block_Realloc( p_block, |
|---|
| | 504 | 0, |
|---|
| | 505 | p_block->i_buffer-i_bytes_in_speex_frame ); |
|---|
| | 506 | *pp_block = p_block; |
|---|
| | 507 | } |
|---|
| | 508 | else |
|---|
| | 509 | { |
|---|
| | 510 | speex_bits_reset( &p_sys->bits ); |
|---|
| | 511 | } |
|---|
| | 512 | |
|---|
| | 513 | free( p_frame_holder ); |
|---|
| | 514 | return SendPacket( p_dec, p_oggpacket /*Not used*/, p_new_block); |
|---|
| | 515 | } |
|---|
| | 516 | else |
|---|
| | 517 | { |
|---|
| | 518 | return SendPacket( p_dec, p_oggpacket, p_block ); |
|---|
| | 519 | } |
|---|
| | 535 | static aout_buffer_t *DecodeRtpSpeexPacket( decoder_t *p_dec, block_t **pp_block ) |
|---|
| | 536 | { |
|---|
| | 537 | block_t *p_speex_bit_block = *pp_block; |
|---|
| | 538 | decoder_sys_t *p_sys = p_dec->p_sys; |
|---|
| | 539 | aout_buffer_t *p_aout_buffer; |
|---|
| | 540 | int i_decode_ret; |
|---|
| | 541 | unsigned int i_speex_frame_size; |
|---|
| | 542 | |
|---|
| | 543 | if ( !p_speex_bit_block || p_speex_bit_block->i_pts == 0 ) return NULL; |
|---|
| | 544 | |
|---|
| | 545 | /* |
|---|
| | 546 | If the SpeexBits buffer size is 0 (a default value), |
|---|
| | 547 | we know that a proper initialization has not yet been done. |
|---|
| | 548 | */ |
|---|
| | 549 | if ( p_sys->bits.buf_size==0 ) |
|---|
| | 550 | { |
|---|
| | 551 | p_sys->p_header = (SpeexHeader *)malloc(sizeof(SpeexHeader)); |
|---|
| | 552 | if ( !p_sys->p_header ) |
|---|
| | 553 | { |
|---|
| | 554 | msg_Err( p_dec, "Could not allocate a Speex header."); |
|---|
| | 555 | return NULL; |
|---|
| | 556 | } |
|---|
| | 557 | speex_init_header( p_sys->p_header,p_sys->rtp_rate,1,&speex_nb_mode ); |
|---|
| | 558 | speex_bits_init( &p_sys->bits ); |
|---|
| | 559 | p_sys->p_state = speex_decoder_init( &speex_nb_mode ); |
|---|
| | 560 | if ( !p_sys->p_state ) |
|---|
| | 561 | { |
|---|
| | 562 | msg_Err( p_dec, "Could not allocate a Speex decoder." ); |
|---|
| | 563 | free( p_sys->p_header ); |
|---|
| | 564 | return NULL; |
|---|
| | 565 | } |
|---|
| | 566 | |
|---|
| | 567 | /* |
|---|
| | 568 | Assume that variable bit rate is enabled. Also assume |
|---|
| | 569 | that there is only one frame per packet. |
|---|
| | 570 | */ |
|---|
| | 571 | p_sys->p_header->vbr = 1; |
|---|
| | 572 | p_sys->p_header->frames_per_packet = 1; |
|---|
| | 573 | |
|---|
| | 574 | p_dec->fmt_out.audio.i_channels = p_sys->p_header->nb_channels; |
|---|
| | 575 | p_dec->fmt_out.audio.i_physical_channels = |
|---|
| | 576 | p_dec->fmt_out.audio.i_original_channels = |
|---|
| | 577 | pi_channels_maps[p_sys->p_header->nb_channels]; |
|---|
| | 578 | p_dec->fmt_out.audio.i_rate = p_sys->p_header->rate; |
|---|
| | 579 | |
|---|
| | 580 | if ( speex_mode_query( &speex_nb_mode, |
|---|
| | 581 | SPEEX_MODE_FRAME_SIZE, |
|---|
| | 582 | &i_speex_frame_size ) ) |
|---|
| | 583 | { |
|---|
| | 584 | msg_Err( p_dec, "Could not determine the frame size." ); |
|---|
| | 585 | speex_decoder_destroy( p_sys->p_state ); |
|---|
| | 586 | free( p_sys->p_header ); |
|---|
| | 587 | return NULL; |
|---|
| | 588 | } |
|---|
| | 589 | p_dec->fmt_out.audio.i_bytes_per_frame = i_speex_frame_size; |
|---|
| | 590 | |
|---|
| | 591 | aout_DateInit(&p_sys->end_date, p_sys->p_header->rate); |
|---|
| | 592 | } |
|---|
| | 593 | |
|---|
| | 594 | /* |
|---|
| | 595 | If the SpeexBits are initialized but there is |
|---|
| | 596 | still no header, an error must be thrown. |
|---|
| | 597 | */ |
|---|
| | 598 | if ( !p_sys->p_header ) |
|---|
| | 599 | { |
|---|
| | 600 | msg_Err( p_dec, "There is no valid Speex header found." ); |
|---|
| | 601 | return NULL; |
|---|
| | 602 | } |
|---|
| | 603 | *pp_block = NULL; |
|---|
| | 604 | |
|---|
| | 605 | if ( !aout_DateGet( &p_sys->end_date ) ) |
|---|
| | 606 | aout_DateSet( &p_sys->end_date, p_speex_bit_block->i_dts ); |
|---|
| | 607 | |
|---|
| | 608 | /* |
|---|
| | 609 | Ask for a new audio output buffer and make sure |
|---|
| | 610 | we get one. |
|---|
| | 611 | */ |
|---|
| | 612 | p_aout_buffer = p_dec->pf_aout_buffer_new( p_dec, |
|---|
| | 613 | p_sys->p_header->frame_size ); |
|---|
| | 614 | if ( !p_aout_buffer || p_aout_buffer->i_nb_bytes == 0 ) |
|---|
| | 615 | { |
|---|
| | 616 | msg_Err(p_dec, "Oops: No new buffer was returned!"); |
|---|
| | 617 | return NULL; |
|---|
| | 618 | } |
|---|
| | 619 | |
|---|
| | 620 | /* |
|---|
| | 621 | Read the Speex payload into the SpeexBits buffer. |
|---|
| | 622 | */ |
|---|
| | 623 | speex_bits_read_from( &p_sys->bits, |
|---|
| | 624 | (char*)p_speex_bit_block->p_buffer, |
|---|
| | 625 | p_speex_bit_block->i_buffer ); |
|---|
| | 626 | |
|---|
| | 627 | /* |
|---|
| | 628 | Decode the input and ensure that no errors |
|---|
| | 629 | were encountered. |
|---|
| | 630 | */ |
|---|
| | 631 | i_decode_ret = |
|---|
| | 632 | speex_decode_int( p_sys->p_state,&p_sys->bits,p_aout_buffer->p_buffer ); |
|---|
| | 633 | if ( i_decode_ret < 0 ) |
|---|
| | 634 | { |
|---|
| | 635 | msg_Err( p_dec, "Decoding failed. Perhaps we have a bad stream?" ); |
|---|
| | 636 | return NULL; |
|---|
| | 637 | } |
|---|
| | 638 | |
|---|
| | 639 | /* |
|---|
| | 640 | Handle date management on the audio output buffer. |
|---|
| | 641 | */ |
|---|
| | 642 | p_aout_buffer->start_date = aout_DateGet( &p_sys->end_date ); |
|---|
| | 643 | p_aout_buffer->end_date = aout_DateIncrement( &p_sys->end_date, |
|---|
| | 644 | p_sys->p_header->frame_size ); |
|---|
| | 645 | |
|---|
| | 646 | |
|---|
| | 647 | p_sys->i_frame_in_packet++; |
|---|
| | 648 | block_Release( p_speex_bit_block ); |
|---|
| | 649 | |
|---|
| | 650 | return p_aout_buffer; |
|---|
| | 651 | } |
|---|
| | 652 | |
|---|