| | 2269 | |
|---|
| | 2270 | static int rtp_packetize_spx( sout_stream_t *p_stream, sout_stream_id_t *id, |
|---|
| | 2271 | block_t *in ) |
|---|
| | 2272 | { |
|---|
| | 2273 | uint8_t *p_buffer = in->p_buffer; |
|---|
| | 2274 | int i_data_size, i_payload_size, i_payload_padding; |
|---|
| | 2275 | i_data_size = i_payload_size = in->i_buffer; |
|---|
| | 2276 | i_payload_padding = 0; |
|---|
| | 2277 | block_t *p_out; |
|---|
| | 2278 | |
|---|
| | 2279 | if ( in->i_buffer + 12 > id->i_mtu ) |
|---|
| | 2280 | { |
|---|
| | 2281 | msg_Warn( p_stream, "Cannot send packet larger than output MTU" ); |
|---|
| | 2282 | return VLC_SUCCESS; |
|---|
| | 2283 | } |
|---|
| | 2284 | |
|---|
| | 2285 | /* |
|---|
| | 2286 | RFC for Speex in RTP says that each packet must end on an octet |
|---|
| | 2287 | boundary. So, we check to see if the number of bytes % 4 is zero. |
|---|
| | 2288 | If not, we have to add some padding. |
|---|
| | 2289 | |
|---|
| | 2290 | This MAY be overkill since packetization is handled elsewhere and |
|---|
| | 2291 | appears to ensure the octet boundary. However, better safe than |
|---|
| | 2292 | sorry. |
|---|
| | 2293 | */ |
|---|
| | 2294 | if ( i_payload_size % 4 ) |
|---|
| | 2295 | { |
|---|
| | 2296 | i_payload_padding = 4 - ( i_payload_size % 4 ); |
|---|
| | 2297 | i_payload_size += i_payload_padding; |
|---|
| | 2298 | } |
|---|
| | 2299 | |
|---|
| | 2300 | /* |
|---|
| | 2301 | Allocate a new RTP p_output block of the appropriate size. |
|---|
| | 2302 | Allow for 12 extra bytes of RTP header. |
|---|
| | 2303 | */ |
|---|
| | 2304 | p_out = block_New( p_stream, 12 + i_payload_size ); |
|---|
| | 2305 | |
|---|
| | 2306 | if ( i_payload_padding ) |
|---|
| | 2307 | { |
|---|
| | 2308 | /* |
|---|
| | 2309 | The padding is required to be a zero followed by all 1s. |
|---|
| | 2310 | */ |
|---|
| | 2311 | char c_first_pad, c_remaining_pad; |
|---|
| | 2312 | c_first_pad = 0x7F; |
|---|
| | 2313 | c_remaining_pad = 0xFF; |
|---|
| | 2314 | |
|---|
| | 2315 | /* |
|---|
| | 2316 | Allow for 12 bytes before the i_data_size because |
|---|
| | 2317 | of the expected RTP header added during |
|---|
| | 2318 | rtp_packetize_common. |
|---|
| | 2319 | */ |
|---|
| | 2320 | p_out->p_buffer[12 + i_data_size] = c_first_pad; |
|---|
| | 2321 | switch (i_payload_padding) |
|---|
| | 2322 | { |
|---|
| | 2323 | case 2: |
|---|
| | 2324 | p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad; |
|---|
| | 2325 | break; |
|---|
| | 2326 | case 3: |
|---|
| | 2327 | p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad; |
|---|
| | 2328 | p_out->p_buffer[12 + i_data_size + 2] = c_remaining_pad; |
|---|
| | 2329 | break; |
|---|
| | 2330 | } |
|---|
| | 2331 | } |
|---|
| | 2332 | |
|---|
| | 2333 | /* Add the RTP header to our p_output buffer. */ |
|---|
| | 2334 | rtp_packetize_common( id, p_out, 0, (in->i_pts > 0 ? in->i_pts : in->i_dts) ); |
|---|
| | 2335 | /* Copy the Speex payload to the p_output buffer */ |
|---|
| | 2336 | memcpy( &p_out->p_buffer[12], p_buffer, i_data_size ); |
|---|
| | 2337 | |
|---|
| | 2338 | p_out->i_buffer = 12 + i_payload_size; |
|---|
| | 2339 | p_out->i_dts = in->i_dts; |
|---|
| | 2340 | p_out->i_length = in->i_length; |
|---|
| | 2341 | |
|---|
| | 2342 | /* Queue the buffer for actual transmission. */ |
|---|
| | 2343 | rtp_packetize_send( id, p_out ); |
|---|
| | 2344 | return VLC_SUCCESS; |
|---|
| | 2345 | } |
|---|