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