]> git.sesse.net Git - vlc/blob - modules/stream_out/rtpfmt.c
call UpdateRate when rate changes, add myself to authors
[vlc] / modules / stream_out / rtpfmt.c
1 /*****************************************************************************
2  * rtp.c: rtp stream output module
3  *****************************************************************************
4  * Copyright (C) 2003-2004 the VideoLAN team
5  * Copyright © 2007 Rémi Denis-Courmont
6  * $Id$
7  *
8  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #include <vlc/vlc.h>
26 #include <vlc_sout.h>
27 #include <vlc_block.h>
28
29 #include "rtp.h"
30
31 int rtp_packetize_mpa( sout_stream_t *p_stream, sout_stream_id_t *id,
32                        block_t *in )
33 {
34     int     i_max   = rtp_mtu (id) - 4; /* payload max in one packet */
35     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
36
37     uint8_t *p_data = in->p_buffer;
38     int     i_data  = in->i_buffer;
39     int     i;
40
41     for( i = 0; i < i_count; i++ )
42     {
43         int           i_payload = __MIN( i_max, i_data );
44         block_t *out = block_New( p_stream, 16 + i_payload );
45
46         /* rtp common header */
47         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
48         /* mbz set to 0 */
49         out->p_buffer[12] = 0;
50         out->p_buffer[13] = 0;
51         /* fragment offset in the current frame */
52         out->p_buffer[14] = ( (i*i_max) >> 8 )&0xff;
53         out->p_buffer[15] = ( (i*i_max)      )&0xff;
54         memcpy( &out->p_buffer[16], p_data, i_payload );
55
56         out->i_buffer   = 16 + i_payload;
57         out->i_dts    = in->i_dts + i * in->i_length / i_count;
58         out->i_length = in->i_length / i_count;
59
60         rtp_packetize_send( id, out );
61
62         p_data += i_payload;
63         i_data -= i_payload;
64     }
65
66     return VLC_SUCCESS;
67 }
68
69 /* rfc2250 */
70 int rtp_packetize_mpv( sout_stream_t *p_stream, sout_stream_id_t *id,
71                        block_t *in )
72 {
73     int     i_max   = rtp_mtu (id) - 4; /* payload max in one packet */
74     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
75
76     uint8_t *p_data = in->p_buffer;
77     int     i_data  = in->i_buffer;
78     int     i;
79     int     b_sequence_start = 0;
80     int     i_temporal_ref = 0;
81     int     i_picture_coding_type = 0;
82     int     i_fbv = 0, i_bfc = 0, i_ffv = 0, i_ffc = 0;
83     int     b_start_slice = 0;
84
85     /* preparse this packet to get some info */
86     if( in->i_buffer > 4 )
87     {
88         uint8_t *p = p_data;
89         int      i_rest = in->i_buffer;
90
91         for( ;; )
92         {
93             while( i_rest > 4 &&
94                    ( p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x01 ) )
95             {
96                 p++;
97                 i_rest--;
98             }
99             if( i_rest <= 4 )
100             {
101                 break;
102             }
103             p += 3;
104             i_rest -= 4;
105
106             if( *p == 0xb3 )
107             {
108                 /* sequence start code */
109                 b_sequence_start = 1;
110             }
111             else if( *p == 0x00 && i_rest >= 4 )
112             {
113                 /* picture */
114                 i_temporal_ref = ( p[1] << 2) |((p[2]>>6)&0x03);
115                 i_picture_coding_type = (p[2] >> 3)&0x07;
116
117                 if( i_rest >= 4 && ( i_picture_coding_type == 2 ||
118                                     i_picture_coding_type == 3 ) )
119                 {
120                     i_ffv = (p[3] >> 2)&0x01;
121                     i_ffc = ((p[3]&0x03) << 1)|((p[4]>>7)&0x01);
122                     if( i_rest > 4 && i_picture_coding_type == 3 )
123                     {
124                         i_fbv = (p[4]>>6)&0x01;
125                         i_bfc = (p[4]>>3)&0x07;
126                     }
127                 }
128             }
129             else if( *p <= 0xaf )
130             {
131                 b_start_slice = 1;
132             }
133         }
134     }
135
136     for( i = 0; i < i_count; i++ )
137     {
138         int           i_payload = __MIN( i_max, i_data );
139         block_t *out = block_New( p_stream,
140                                              16 + i_payload );
141         uint32_t      h = ( i_temporal_ref << 16 )|
142                           ( b_sequence_start << 13 )|
143                           ( b_start_slice << 12 )|
144                           ( i == i_count - 1 ? 1 << 11 : 0 )|
145                           ( i_picture_coding_type << 8 )|
146                           ( i_fbv << 7 )|( i_bfc << 4 )|( i_ffv << 3 )|i_ffc;
147
148         /* rtp common header */
149         rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
150                               in->i_pts > 0 ? in->i_pts : in->i_dts );
151
152         /* MBZ:5 T:1 TR:10 AN:1 N:1 S:1 B:1 E:1 P:3 FBV:1 BFC:3 FFV:1 FFC:3 */
153         out->p_buffer[12] = ( h >> 24 )&0xff;
154         out->p_buffer[13] = ( h >> 16 )&0xff;
155         out->p_buffer[14] = ( h >>  8 )&0xff;
156         out->p_buffer[15] = ( h       )&0xff;
157
158         memcpy( &out->p_buffer[16], p_data, i_payload );
159
160         out->i_buffer   = 16 + i_payload;
161         out->i_dts    = in->i_dts + i * in->i_length / i_count;
162         out->i_length = in->i_length / i_count;
163
164         rtp_packetize_send( id, out );
165
166         p_data += i_payload;
167         i_data -= i_payload;
168     }
169
170     return VLC_SUCCESS;
171 }
172
173 int rtp_packetize_ac3( sout_stream_t *p_stream, sout_stream_id_t *id,
174                        block_t *in )
175 {
176     int     i_max   = rtp_mtu (id) - 2; /* payload max in one packet */
177     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
178
179     uint8_t *p_data = in->p_buffer;
180     int     i_data  = in->i_buffer;
181     int     i;
182
183     for( i = 0; i < i_count; i++ )
184     {
185         int           i_payload = __MIN( i_max, i_data );
186         block_t *out = block_New( p_stream, 14 + i_payload );
187
188         /* rtp common header */
189         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
190         /* unit count */
191         out->p_buffer[12] = 1;
192         /* unit header */
193         out->p_buffer[13] = 0x00;
194         /* data */
195         memcpy( &out->p_buffer[14], p_data, i_payload );
196
197         out->i_buffer   = 14 + i_payload;
198         out->i_dts    = in->i_dts + i * in->i_length / i_count;
199         out->i_length = in->i_length / i_count;
200
201         rtp_packetize_send( id, out );
202
203         p_data += i_payload;
204         i_data -= i_payload;
205     }
206
207     return VLC_SUCCESS;
208 }
209
210 int rtp_packetize_split( sout_stream_t *p_stream, sout_stream_id_t *id,
211                          block_t *in )
212 {
213     int     i_max   = rtp_mtu (id); /* payload max in one packet */
214     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
215
216     uint8_t *p_data = in->p_buffer;
217     int     i_data  = in->i_buffer;
218     int     i;
219
220     for( i = 0; i < i_count; i++ )
221     {
222         int           i_payload = __MIN( i_max, i_data );
223         block_t *out = block_New( p_stream, 12 + i_payload );
224
225         /* rtp common header */
226         rtp_packetize_common( id, out, (i == i_count - 1),
227                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
228         memcpy( &out->p_buffer[12], p_data, i_payload );
229
230         out->i_buffer   = 12 + i_payload;
231         out->i_dts    = in->i_dts + i * in->i_length / i_count;
232         out->i_length = in->i_length / i_count;
233
234         rtp_packetize_send( id, out );
235
236         p_data += i_payload;
237         i_data -= i_payload;
238     }
239
240     return VLC_SUCCESS;
241 }
242
243 /* rfc3016 */
244 int rtp_packetize_mp4a_latm( sout_stream_t *p_stream, sout_stream_id_t *id,
245                              block_t *in )
246 {
247     int     i_max   = rtp_mtu (id) - 2;              /* payload max in one packet */
248     int     latmhdrsize = in->i_buffer / 0xff + 1;
249     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
250
251     uint8_t *p_data = in->p_buffer, *p_header = NULL;
252     int     i_data  = in->i_buffer;
253     int     i;
254
255     for( i = 0; i < i_count; i++ )
256     {
257         int     i_payload = __MIN( i_max, i_data );
258         block_t *out;
259
260         if( i != 0 )
261             latmhdrsize = 0;
262         out = block_New( p_stream, 12 + latmhdrsize + i_payload );
263
264         /* rtp common header */
265         rtp_packetize_common( id, out, ((i == i_count - 1) ? 1 : 0),
266                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
267
268         if( i == 0 )
269         {
270             int tmp = in->i_buffer;
271
272             p_header=out->p_buffer+12;
273             while( tmp > 0xfe )
274             {
275                 *p_header = 0xff;
276                 p_header++;
277                 tmp -= 0xff;
278             }
279             *p_header = tmp;
280         }
281
282         memcpy( &out->p_buffer[12+latmhdrsize], p_data, i_payload );
283
284         out->i_buffer   = 12 + latmhdrsize + i_payload;
285         out->i_dts    = in->i_dts + i * in->i_length / i_count;
286         out->i_length = in->i_length / i_count;
287
288         rtp_packetize_send( id, out );
289
290         p_data += i_payload;
291         i_data -= i_payload;
292     }
293
294     return VLC_SUCCESS;
295 }
296
297 int rtp_packetize_l16( sout_stream_t *p_stream, sout_stream_id_t *id,
298                        block_t *in )
299 {
300     const uint8_t *p_data = in->p_buffer;
301     size_t i_data  = in->i_buffer;
302     size_t i_plen = 2 * rtp_plen (id, 20);
303
304     for( unsigned i_packet = 0; i_data > 0; i_packet++ )
305     {
306         int           i_payload = __MIN( i_plen, i_data );
307         block_t *out = block_New( p_stream, 12 + i_payload );
308
309         /* rtp common header */
310         rtp_packetize_common( id, out, 0,
311                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
312         memcpy( &out->p_buffer[12], p_data, i_payload );
313
314         out->i_buffer = 12 + i_payload;
315         out->i_dts    = in->i_dts + i_packet * 20000;
316         out->i_length = i_payload * 20000 / i_plen;
317
318         rtp_packetize_send( id, out );
319
320         p_data += i_payload;
321         i_data -= i_payload;
322     }
323
324     return VLC_SUCCESS;
325 }
326
327 int rtp_packetize_l8( sout_stream_t *p_stream, sout_stream_id_t *id,
328                       block_t *in )
329 {
330     const uint8_t *p_data = in->p_buffer;
331     size_t i_data  = in->i_buffer;
332     size_t i_plen = rtp_plen (id, 20);
333
334     for( unsigned i_packet = 0; i_data > 0; i_packet++ )
335     {
336         int           i_payload = __MIN( i_plen, i_data );
337         block_t *out = block_New( p_stream, 12 + i_payload );
338
339         /* rtp common header */
340         rtp_packetize_common( id, out, 0,
341                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
342         memcpy( &out->p_buffer[12], p_data, i_payload );
343
344         out->i_buffer = 12 + i_payload;
345         out->i_dts    = in->i_dts + i_packet * 20000;
346         out->i_length = i_payload * 20000 / i_plen;
347
348         rtp_packetize_send( id, out );
349
350         p_data += i_payload;
351         i_data -= i_payload;
352     }
353
354     return VLC_SUCCESS;
355 }
356
357 int rtp_packetize_mp4a( sout_stream_t *p_stream, sout_stream_id_t *id,
358                         block_t *in )
359 {
360     int     i_max   = rtp_mtu (id) - 4; /* payload max in one packet */
361     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
362
363     uint8_t *p_data = in->p_buffer;
364     int     i_data  = in->i_buffer;
365     int     i;
366
367     for( i = 0; i < i_count; i++ )
368     {
369         int           i_payload = __MIN( i_max, i_data );
370         block_t *out = block_New( p_stream, 16 + i_payload );
371
372         /* rtp common header */
373         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
374                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
375         /* AU headers */
376         /* AU headers length (bits) */
377         out->p_buffer[12] = 0;
378         out->p_buffer[13] = 2*8;
379         /* for each AU length 13 bits + idx 3bits, */
380         out->p_buffer[14] = ( in->i_buffer >> 5 )&0xff;
381         out->p_buffer[15] = ( (in->i_buffer&0xff)<<3 )|0;
382
383         memcpy( &out->p_buffer[16], p_data, i_payload );
384
385         out->i_buffer   = 16 + i_payload;
386         out->i_dts    = in->i_dts + i * in->i_length / i_count;
387         out->i_length = in->i_length / i_count;
388
389         rtp_packetize_send( id, out );
390
391         p_data += i_payload;
392         i_data -= i_payload;
393     }
394
395     return VLC_SUCCESS;
396 }
397
398
399 /* rfc2429 */
400 #define RTP_H263_HEADER_SIZE (2)  // plen = 0
401 #define RTP_H263_PAYLOAD_START (14)  // plen = 0
402 int rtp_packetize_h263( sout_stream_t *p_stream, sout_stream_id_t *id,
403                         block_t *in )
404 {
405     uint8_t *p_data = in->p_buffer;
406     int     i_data  = in->i_buffer;
407     int     i;
408     int     i_max   = rtp_mtu (id) - RTP_H263_HEADER_SIZE; /* payload max in one packet */
409     int     i_count;
410     int     b_p_bit;
411     int     b_v_bit = 0; // no pesky error resilience
412     int     i_plen = 0; // normally plen=0 for PSC packet
413     int     i_pebit = 0; // because plen=0
414     uint16_t h;
415
416     if( i_data < 2 )
417     {
418         return VLC_EGENERIC;
419     }
420     if( p_data[0] || p_data[1] )
421     {
422         return VLC_EGENERIC;
423     }
424     /* remove 2 leading 0 bytes */
425     p_data += 2;
426     i_data -= 2;
427     i_count = ( i_data + i_max - 1 ) / i_max;
428
429     for( i = 0; i < i_count; i++ )
430     {
431         int      i_payload = __MIN( i_max, i_data );
432         block_t *out = block_New( p_stream,
433                                   RTP_H263_PAYLOAD_START + i_payload );
434         b_p_bit = (i == 0) ? 1 : 0;
435         h = ( b_p_bit << 10 )|
436             ( b_v_bit << 9  )|
437             ( i_plen  << 3  )|
438               i_pebit;
439
440         /* rtp common header */
441         //b_m_bit = 1; // always contains end of frame
442         rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
443                               in->i_pts > 0 ? in->i_pts : in->i_dts );
444
445         /* h263 header */
446         out->p_buffer[12] = ( h >>  8 )&0xff;
447         out->p_buffer[13] = ( h       )&0xff;
448         memcpy( &out->p_buffer[RTP_H263_PAYLOAD_START], p_data, i_payload );
449
450         out->i_buffer = RTP_H263_PAYLOAD_START + i_payload;
451         out->i_dts    = in->i_dts + i * in->i_length / i_count;
452         out->i_length = in->i_length / i_count;
453
454         rtp_packetize_send( id, out );
455
456         p_data += i_payload;
457         i_data -= i_payload;
458     }
459
460     return VLC_SUCCESS;
461 }
462
463 /* rfc3984 */
464 int
465 rtp_packetize_h264_nal( sout_stream_t *p_stream, sout_stream_id_t *id,
466                         const uint8_t *p_data, int i_data, int64_t i_pts,
467                         int64_t i_dts, vlc_bool_t b_last, int64_t i_length )
468 {
469     const int i_max = rtp_mtu (id); /* payload max in one packet */
470     int i_nal_hdr;
471     int i_nal_type;
472
473     if( i_data < 5 )
474         return VLC_SUCCESS;
475
476     i_nal_hdr = p_data[3];
477     i_nal_type = i_nal_hdr&0x1f;
478
479     /* Skip start code */
480     p_data += 3;
481     i_data -= 3;
482
483     /* */
484     if( i_data <= i_max )
485     {
486         /* Single NAL unit packet */
487         block_t *out = block_New( p_stream, 12 + i_data );
488         out->i_dts    = i_dts;
489         out->i_length = i_length;
490
491         /* */
492         rtp_packetize_common( id, out, b_last, i_pts );
493         out->i_buffer = 12 + i_data;
494
495         memcpy( &out->p_buffer[12], p_data, i_data );
496
497         rtp_packetize_send( id, out );
498     }
499     else
500     {
501         /* FU-A Fragmentation Unit without interleaving */
502         const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2);
503         int i;
504
505         p_data++;
506         i_data--;
507
508         for( i = 0; i < i_count; i++ )
509         {
510             const int i_payload = __MIN( i_data, i_max-2 );
511             block_t *out = block_New( p_stream, 12 + 2 + i_payload );
512             out->i_dts    = i_dts + i * i_length / i_count;
513             out->i_length = i_length / i_count;
514
515             /* */
516             rtp_packetize_common( id, out, (b_last && i_payload == i_data), i_pts );
517             out->i_buffer = 14 + i_payload;
518
519             /* FU indicator */
520             out->p_buffer[12] = 0x00 | (i_nal_hdr & 0x60) | 28;
521             /* FU header */
522             out->p_buffer[13] = ( i == 0 ? 0x80 : 0x00 ) | ( (i == i_count-1) ? 0x40 : 0x00 )  | i_nal_type;
523             memcpy( &out->p_buffer[14], p_data, i_payload );
524
525             rtp_packetize_send( id, out );
526
527             i_data -= i_payload;
528             p_data += i_payload;
529         }
530     }
531     return VLC_SUCCESS;
532 }
533
534 int rtp_packetize_h264( sout_stream_t *p_stream, sout_stream_id_t *id,
535                         block_t *in )
536 {
537     const uint8_t *p_buffer = in->p_buffer;
538     int i_buffer = in->i_buffer;
539
540     while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] != 1 ) )
541     {
542         i_buffer--;
543         p_buffer++;
544     }
545
546     /* Split nal units */
547     while( i_buffer > 4 )
548     {
549         int i_offset;
550         int i_size = i_buffer;
551         int i_skip = i_buffer;
552
553         /* search nal end */
554         for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++)
555         {
556             if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 )
557             {
558                 /* we found another startcode */
559                 i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 : 0);
560                 i_skip = i_offset;
561                 break;
562             }
563         }
564         /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */
565         rtp_packetize_h264_nal( p_stream, id, p_buffer, i_size,
566                                 (in->i_pts > 0 ? in->i_pts : in->i_dts), in->i_dts,
567                                 (i_size >= i_buffer), in->i_length * i_size / in->i_buffer );
568
569         i_buffer -= i_skip;
570         p_buffer += i_skip;
571     }
572     return VLC_SUCCESS;
573 }
574
575 int rtp_packetize_amr( sout_stream_t *p_stream, sout_stream_id_t *id,
576                        block_t *in )
577 {
578     int     i_max   = rtp_mtu (id) - 2; /* payload max in one packet */
579     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
580
581     uint8_t *p_data = in->p_buffer;
582     int     i_data  = in->i_buffer;
583     int     i;
584
585     /* Only supports octet-aligned mode */
586     for( i = 0; i < i_count; i++ )
587     {
588         int           i_payload = __MIN( i_max, i_data );
589         block_t *out = block_New( p_stream, 14 + i_payload );
590
591         /* rtp common header */
592         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
593                               (in->i_pts > 0 ? in->i_pts : in->i_dts) );
594         /* Payload header */
595         out->p_buffer[12] = 0xF0; /* CMR */
596         out->p_buffer[13] = p_data[0]&0x7C; /* ToC */ /* FIXME: frame type */
597
598         /* FIXME: are we fed multiple frames ? */
599         memcpy( &out->p_buffer[14], p_data+1, i_payload-1 );
600
601         out->i_buffer   = 14 + i_payload-1;
602         out->i_dts    = in->i_dts + i * in->i_length / i_count;
603         out->i_length = in->i_length / i_count;
604
605         rtp_packetize_send( id, out );
606
607         p_data += i_payload;
608         i_data -= i_payload;
609     }
610
611     return VLC_SUCCESS;
612 }
613
614 int rtp_packetize_t140( sout_stream_t *p_stream, sout_stream_id_t *id,
615                         block_t *in )
616 {
617     const size_t   i_max  = rtp_mtu (id);
618     const uint8_t *p_data = in->p_buffer;
619     size_t         i_data = in->i_buffer;
620
621     for( unsigned i_packet = 0; i_data > 0; i_packet++ )
622     {
623         size_t i_payload = i_data;
624
625         /* Make sure we stop on an UTF-8 character boundary
626          * (assuming the input is valid UTF-8) */
627         if( i_data > i_max )
628         {
629             i_payload = i_max;
630
631             while( ( p_data[i_payload] & 0xC0 ) == 0x80 )
632             {
633                 if( i_payload == 0 )
634                     return VLC_SUCCESS; /* fishy input! */
635
636                 i_payload--;
637             }
638         }
639
640         block_t *out = block_New( p_stream, 12 + i_payload );
641         if( out == NULL )
642             return VLC_SUCCESS;
643
644         rtp_packetize_common( id, out, 0, in->i_pts + i_packet );
645         memcpy( out->p_buffer + 12, p_data, i_payload );
646
647         out->i_buffer = 12 + i_payload;
648         out->i_dts    = out->i_pts;
649         out->i_length = 0;
650
651         rtp_packetize_send( id, out );
652
653         p_data += i_payload;
654         i_data -= i_payload;
655     }
656
657     return VLC_SUCCESS;
658 }
659
660
661 int rtp_packetize_spx( sout_stream_t *p_stream, sout_stream_id_t *id,
662                        block_t *in )
663 {
664     uint8_t *p_buffer = in->p_buffer;
665     int i_data_size, i_payload_size, i_payload_padding;
666     i_data_size = i_payload_size = in->i_buffer;
667     i_payload_padding = 0;
668     block_t *p_out;
669
670     if ( in->i_buffer > rtp_mtu (id) )
671     {
672         msg_Warn( p_stream, "Cannot send packet larger than output MTU" );
673         return VLC_SUCCESS;
674     }
675
676     /*
677       RFC for Speex in RTP says that each packet must end on an octet 
678       boundary. So, we check to see if the number of bytes % 4 is zero.
679       If not, we have to add some padding. 
680
681       This MAY be overkill since packetization is handled elsewhere and 
682       appears to ensure the octet boundary. However, better safe than
683       sorry.
684     */
685     if ( i_payload_size % 4 )
686     {
687         i_payload_padding = 4 - ( i_payload_size % 4 );
688         i_payload_size += i_payload_padding;
689     }
690
691     /*
692       Allocate a new RTP p_output block of the appropriate size. 
693       Allow for 12 extra bytes of RTP header. 
694     */
695     p_out = block_New( p_stream, 12 + i_payload_size );
696
697     if ( i_payload_padding )
698     {
699     /*
700       The padding is required to be a zero followed by all 1s.
701     */
702         char c_first_pad, c_remaining_pad;
703         c_first_pad = 0x7F;
704         c_remaining_pad = 0xFF;
705
706         /*
707           Allow for 12 bytes before the i_data_size because
708           of the expected RTP header added during
709           rtp_packetize_common.
710         */
711         p_out->p_buffer[12 + i_data_size] = c_first_pad; 
712         switch (i_payload_padding)
713         {
714           case 2:
715             p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad; 
716             break;
717           case 3:
718             p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad; 
719             p_out->p_buffer[12 + i_data_size + 2] = c_remaining_pad; 
720             break;
721         }
722     }
723
724     /* Add the RTP header to our p_output buffer. */
725     rtp_packetize_common( id, p_out, 0, (in->i_pts > 0 ? in->i_pts : in->i_dts) );
726     /* Copy the Speex payload to the p_output buffer */
727     memcpy( &p_out->p_buffer[12], p_buffer, i_data_size );
728
729     p_out->i_buffer = 12 + i_payload_size;
730     p_out->i_dts = in->i_dts;
731     p_out->i_length = in->i_length;
732
733     /* Queue the buffer for actual transmission. */
734     rtp_packetize_send( id, p_out );
735     return VLC_SUCCESS;
736 }