| | 2554 | |
|---|
| | 2555 | static int rtp_packetize_spx( sout_stream_t *p_stream, sout_stream_id_t *id, |
|---|
| | 2556 | block_t *in ) |
|---|
| | 2557 | { |
|---|
| | 2558 | uint8_t *p_buffer = in->p_buffer; |
|---|
| | 2559 | int i_data_size, i_payload_size, i_payload_padding; |
|---|
| | 2560 | i_data_size = i_payload_size = in->i_buffer; |
|---|
| | 2561 | i_payload_padding = 0; |
|---|
| | 2562 | block_t *p_out; |
|---|
| | 2563 | |
|---|
| | 2564 | if ( in->i_buffer + 12 > id->i_mtu ) |
|---|
| | 2565 | { |
|---|
| | 2566 | msg_Warn( p_stream, "Cannot send packet larger than output MTU" ); |
|---|
| | 2567 | return VLC_SUCCESS; |
|---|
| | 2568 | } |
|---|
| | 2569 | |
|---|
| | 2570 | /* |
|---|
| | 2571 | RFC for Speex in RTP says that each packet must end on an octet |
|---|
| | 2572 | boundary. So, we check to see if the number of bytes % 4 is zero. |
|---|
| | 2573 | If not, we have to add some padding. |
|---|
| | 2574 | |
|---|
| | 2575 | This MAY be overkill since packetization is handled elsewhere and |
|---|
| | 2576 | appears to ensure the octet boundary. However, better safe than |
|---|
| | 2577 | sorry. |
|---|
| | 2578 | */ |
|---|
| | 2579 | if ( i_payload_size % 4 ) |
|---|
| | 2580 | { |
|---|
| | 2581 | i_payload_padding = 4 - ( i_payload_size % 4 ); |
|---|
| | 2582 | i_payload_size += i_payload_padding; |
|---|
| | 2583 | } |
|---|
| | 2584 | |
|---|
| | 2585 | /* |
|---|
| | 2586 | Allocate a new RTP p_output block of the appropriate size. |
|---|
| | 2587 | Allow for 12 extra bytes of RTP header. |
|---|
| | 2588 | */ |
|---|
| | 2589 | p_out = block_New( p_stream, 12 + i_payload_size ); |
|---|
| | 2590 | |
|---|
| | 2591 | if ( i_payload_padding ) |
|---|
| | 2592 | { |
|---|
| | 2593 | /* |
|---|
| | 2594 | The padding is required to be a zero followed by all 1s. |
|---|
| | 2595 | */ |
|---|
| | 2596 | char c_first_pad, c_remaining_pad; |
|---|
| | 2597 | c_first_pad = 0x7F; |
|---|
| | 2598 | c_remaining_pad = 0xFF; |
|---|
| | 2599 | |
|---|
| | 2600 | /* |
|---|
| | 2601 | Allow for 12 bytes before the i_data_size because |
|---|
| | 2602 | of the expected RTP header added during |
|---|
| | 2603 | rtp_packetize_common. |
|---|
| | 2604 | */ |
|---|
| | 2605 | p_out->p_buffer[12 + i_data_size] = c_first_pad; |
|---|
| | 2606 | switch (i_payload_padding) |
|---|
| | 2607 | { |
|---|
| | 2608 | case 2: |
|---|
| | 2609 | p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad; |
|---|
| | 2610 | break; |
|---|
| | 2611 | case 3: |
|---|
| | 2612 | p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad; |
|---|
| | 2613 | p_out->p_buffer[12 + i_data_size + 2] = c_remaining_pad; |
|---|
| | 2614 | break; |
|---|
| | 2615 | } |
|---|
| | 2616 | } |
|---|
| | 2617 | |
|---|
| | 2618 | /* Add the RTP header to our p_output buffer. */ |
|---|
| | 2619 | rtp_packetize_common( id, p_out, 0, (in->i_pts > 0 ? in->i_pts : in->i_dts) ); |
|---|
| | 2620 | /* Copy the Speex payload to the p_output buffer */ |
|---|
| | 2621 | memcpy( &p_out->p_buffer[12], p_buffer, i_data_size ); |
|---|
| | 2622 | |
|---|
| | 2623 | p_out->i_buffer = 12 + i_payload_size; |
|---|
| | 2624 | p_out->i_dts = in->i_dts; |
|---|
| | 2625 | p_out->i_length = in->i_length; |
|---|
| | 2626 | |
|---|
| | 2627 | /* Queue the buffer for actual transmission. */ |
|---|
| | 2628 | rtp_packetize_send( id, p_out ); |
|---|
| | 2629 | return VLC_SUCCESS; |
|---|
| | 2630 | } |