]> git.sesse.net Git - vlc/blob - modules/stream_out/rtpfmt.c
Improve mailmap
[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 #include <vlc_strings.h>
33
34 #include "rtp.h"
35 #include "../demux/xiph.h"
36
37 #include <assert.h>
38
39 static int rtp_packetize_mpa  (sout_stream_id_t *, block_t *);
40 static int rtp_packetize_mpv  (sout_stream_id_t *, block_t *);
41 static int rtp_packetize_ac3  (sout_stream_id_t *, block_t *);
42 static int rtp_packetize_split(sout_stream_id_t *, block_t *);
43 static int rtp_packetize_swab (sout_stream_id_t *, block_t *);
44 static int rtp_packetize_mp4a (sout_stream_id_t *, block_t *);
45 static int rtp_packetize_mp4a_latm (sout_stream_id_t *, block_t *);
46 static int rtp_packetize_h263 (sout_stream_id_t *, block_t *);
47 static int rtp_packetize_h264 (sout_stream_id_t *, block_t *);
48 static int rtp_packetize_amr  (sout_stream_id_t *, block_t *);
49 static int rtp_packetize_spx  (sout_stream_id_t *, block_t *);
50 static int rtp_packetize_t140 (sout_stream_id_t *, block_t *);
51 static int rtp_packetize_g726_16 (sout_stream_id_t *, block_t *);
52 static int rtp_packetize_g726_24 (sout_stream_id_t *, block_t *);
53 static int rtp_packetize_g726_32 (sout_stream_id_t *, block_t *);
54 static int rtp_packetize_g726_40 (sout_stream_id_t *, block_t *);
55 static int rtp_packetize_xiph (sout_stream_id_t *, block_t *);
56
57 #define XIPH_IDENT (0)
58
59 /* Helpers common to xiph codecs (vorbis and theora) */
60
61 static int rtp_xiph_pack_headers(size_t room, void *p_extra, size_t i_extra,
62                                  uint8_t **p_buffer, size_t *i_buffer,
63                                  uint8_t *theora_pixel_fmt)
64 {
65     unsigned packet_size[XIPH_MAX_HEADER_COUNT];
66     void *packet[XIPH_MAX_HEADER_COUNT];
67     unsigned packet_count;
68     int val = xiph_SplitHeaders(packet_size, packet, &packet_count,
69                                 i_extra, p_extra);
70     if (val != VLC_SUCCESS)
71         return val;
72     if (packet_count < 3)
73     {
74         val = VLC_EGENERIC;
75         goto free;
76     }
77
78     if (theora_pixel_fmt != NULL)
79     {
80         if (packet_size[0] < 42)
81         {
82             val = VLC_EGENERIC;
83             goto free;
84         }
85         *theora_pixel_fmt = (((uint8_t *)packet[0])[41] >> 3) & 0x03;
86     }
87
88     unsigned length_size[2] = { 0, 0 };
89     for (int i = 0; i < 2; i++)
90     {
91         unsigned size = packet_size[i];
92         while (size > 0)
93         {
94             length_size[i]++;
95             size >>= 7;
96         }
97     }
98
99     *i_buffer = room + 1 + length_size[0] + length_size[1]
100                 + packet_size[0] + packet_size[1] + packet_size[2];
101     *p_buffer = malloc(*i_buffer);
102     if (*p_buffer == NULL)
103     {
104         val = VLC_ENOMEM;
105         goto free;
106     }
107
108     uint8_t *p = *p_buffer + room;
109     /* Number of headers */
110     *p++ = 2;
111
112     for (int i = 0; i < 2; i++)
113     {
114         unsigned size = length_size[i];
115         while (size > 0)
116         {
117             *p = (packet_size[i] >> (7 * (size - 1))) & 0x7f;
118             if (--size > 0)
119                 *p |= 0x80;
120             p++;
121         }
122     }
123     for (int i = 0; i < 3; i++)
124     {
125         memcpy(p, packet[i], packet_size[i]);
126         p += packet_size[i];
127     }
128
129     val = VLC_SUCCESS;
130 free:
131     for (unsigned i = 0; i < packet_count; i++)
132         free(packet[i]);
133
134     return val;
135 }
136
137 static char *rtp_xiph_b64_oob_config(void *p_extra, size_t i_extra,
138                                      uint8_t *theora_pixel_fmt)
139 {
140     uint8_t *p_buffer;
141     size_t i_buffer;
142     if (rtp_xiph_pack_headers(9, p_extra, i_extra, &p_buffer, &i_buffer,
143                               theora_pixel_fmt) != VLC_SUCCESS)
144         return NULL;
145
146     /* Number of packed headers */
147     SetDWBE(p_buffer, 1);
148     /* Ident */
149     uint32_t ident = XIPH_IDENT;
150     SetWBE(p_buffer + 4, ident >> 8);
151     p_buffer[6] = ident & 0xff;
152     /* Length field */
153     SetWBE(p_buffer + 7, i_buffer);
154
155     char *config = vlc_b64_encode_binary(p_buffer, i_buffer);
156     free(p_buffer);
157     return config;
158 }
159
160 static void sprintf_hexa( char *s, uint8_t *p_data, int i_data )
161 {
162     static const char hex[16] = "0123456789abcdef";
163
164     for( int i = 0; i < i_data; i++ )
165     {
166         s[2*i+0] = hex[(p_data[i]>>4)&0xf];
167         s[2*i+1] = hex[(p_data[i]   )&0xf];
168     }
169     s[2*i_data] = '\0';
170 }
171
172 /* TODO: make this into something more clever than a big switch? */
173 int rtp_get_fmt( vlc_object_t *obj, es_format_t *p_fmt, const char *mux,
174                   rtp_format_t *rtp_fmt )
175 {
176     assert( p_fmt != NULL || mux != NULL );
177
178     /* Dynamic payload type. Payload types are scoped to the RTP
179      * session, and we put each ES in its own session, so no risk of
180      * conflict. */
181     rtp_fmt->payload_type = 96;
182     rtp_fmt->cat = mux != NULL ? VIDEO_ES : p_fmt->i_cat;
183     if( rtp_fmt->cat == AUDIO_ES )
184     {
185         rtp_fmt->clock_rate = p_fmt->audio.i_rate;
186         rtp_fmt->channels = p_fmt->audio.i_channels;
187     }
188     else
189         rtp_fmt->clock_rate = 90000; /* most common case for video */
190     /* Stream bitrate in kbps */
191     rtp_fmt->bitrate = p_fmt != NULL ? p_fmt->i_bitrate/1000 : 0;
192     rtp_fmt->fmtp = NULL;
193
194     if( mux != NULL )
195     {
196         if( strncmp( mux, "ts", 2 ) == 0 )
197         {
198             rtp_fmt->payload_type = 33;
199             rtp_fmt->ptname = "MP2T";
200         }
201         else
202             rtp_fmt->ptname = "MP2P";
203         return VLC_SUCCESS;
204     }
205
206     switch( p_fmt->i_codec )
207     {
208         case VLC_CODEC_MULAW:
209             if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
210                 rtp_fmt->payload_type = 0;
211             rtp_fmt->ptname = "PCMU";
212             rtp_fmt->pf_packetize = rtp_packetize_split;
213             break;
214         case VLC_CODEC_ALAW:
215             if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
216                 rtp_fmt->payload_type = 8;
217             rtp_fmt->ptname = "PCMA";
218             rtp_fmt->pf_packetize = rtp_packetize_split;
219             break;
220         case VLC_CODEC_S16B:
221         case VLC_CODEC_S16L:
222             if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 44100 )
223             {
224                 rtp_fmt->payload_type = 11;
225             }
226             else if( p_fmt->audio.i_channels == 2 &&
227                      p_fmt->audio.i_rate == 44100 )
228             {
229                 rtp_fmt->payload_type = 10;
230             }
231             rtp_fmt->ptname = "L16";
232             if( p_fmt->i_codec == VLC_CODEC_S16B )
233                 rtp_fmt->pf_packetize = rtp_packetize_split;
234             else
235                 rtp_fmt->pf_packetize = rtp_packetize_swab;
236             break;
237         case VLC_CODEC_U8:
238             rtp_fmt->ptname = "L8";
239             rtp_fmt->pf_packetize = rtp_packetize_split;
240             break;
241         case VLC_CODEC_S24B:
242             rtp_fmt->ptname = "L24";
243             rtp_fmt->pf_packetize = rtp_packetize_split;
244             break;
245         case VLC_CODEC_MPGA:
246             rtp_fmt->payload_type = 14;
247             rtp_fmt->ptname = "MPA";
248             rtp_fmt->clock_rate = 90000; /* not 44100 */
249             rtp_fmt->pf_packetize = rtp_packetize_mpa;
250             break;
251         case VLC_CODEC_MPGV:
252             rtp_fmt->payload_type = 32;
253             rtp_fmt->ptname = "MPV";
254             rtp_fmt->pf_packetize = rtp_packetize_mpv;
255             break;
256         case VLC_CODEC_ADPCM_G726:
257             switch( p_fmt->i_bitrate / 1000 )
258             {
259             case 16:
260                 rtp_fmt->ptname = "G726-16";
261                 rtp_fmt->pf_packetize = rtp_packetize_g726_16;
262                 break;
263             case 24:
264                 rtp_fmt->ptname = "G726-24";
265                 rtp_fmt->pf_packetize = rtp_packetize_g726_24;
266                 break;
267             case 32:
268                 rtp_fmt->ptname = "G726-32";
269                 rtp_fmt->pf_packetize = rtp_packetize_g726_32;
270                 break;
271             case 40:
272                 rtp_fmt->ptname = "G726-40";
273                 rtp_fmt->pf_packetize = rtp_packetize_g726_40;
274                 break;
275             default:
276                 msg_Err( obj, "cannot add this stream (unsupported "
277                          "G.726 bit rate: %u)", p_fmt->i_bitrate );
278                 return VLC_EGENERIC;
279             }
280             break;
281         case VLC_CODEC_A52:
282             rtp_fmt->ptname = "ac3";
283             rtp_fmt->pf_packetize = rtp_packetize_ac3;
284             break;
285         case VLC_CODEC_H263:
286             rtp_fmt->ptname = "H263-1998";
287             rtp_fmt->pf_packetize = rtp_packetize_h263;
288             break;
289         case VLC_CODEC_H264:
290             rtp_fmt->ptname = "H264";
291             rtp_fmt->pf_packetize = rtp_packetize_h264;
292             rtp_fmt->fmtp = NULL;
293
294             if( p_fmt->i_extra > 0 )
295             {
296                 uint8_t *p_buffer = p_fmt->p_extra;
297                 int     i_buffer = p_fmt->i_extra;
298                 char    *p_64_sps = NULL;
299                 char    *p_64_pps = NULL;
300                 char    hexa[6+1];
301
302                 while( i_buffer > 4 )
303                 {
304                     int i_offset    = 0;
305                     int i_size      = 0;
306
307                     while( p_buffer[0] != 0 || p_buffer[1] != 0 ||
308                            p_buffer[2] != 1 )
309                     {
310                         p_buffer++;
311                         i_buffer--;
312                         if( i_buffer == 0 ) break;
313                     }
314
315                     if( i_buffer < 4 || memcmp(p_buffer, "\x00\x00\x01", 3 ) )
316                     {
317                         msg_Dbg( obj, "No startcode found..");
318                         break;
319                     }
320                     p_buffer += 3;
321                     i_buffer -= 3;
322
323                     const int i_nal_type = p_buffer[0]&0x1f;
324
325                     msg_Dbg( obj, "we found a startcode for NAL with TYPE:%d", i_nal_type );
326
327                     i_size = i_buffer;
328                     for( i_offset = 0; i_offset+2 < i_buffer ; i_offset++)
329                     {
330                         if( !memcmp(p_buffer + i_offset, "\x00\x00\x01", 3 ) )
331                         {
332                             /* we found another startcode */
333                             while( i_offset > 0 && 0 == p_buffer[ i_offset - 1 ] )
334                                 i_offset--;
335                             i_size = i_offset;
336                             break;
337                         }
338                     }
339
340                     if( i_size == 0 )
341                     {
342                         msg_Dbg( obj, "No-info found in nal ");
343                         continue;
344                     }
345
346                     if( i_nal_type == 7 )
347                     {
348                         free( p_64_sps );
349                         p_64_sps = vlc_b64_encode_binary( p_buffer, i_size );
350                         /* XXX: nothing ensures that i_size >= 4 ?? */
351                         sprintf_hexa( hexa, &p_buffer[1], 3 );
352                     }
353                     else if( i_nal_type == 8 )
354                     {
355                         free( p_64_pps );
356                         p_64_pps = vlc_b64_encode_binary( p_buffer, i_size );
357                     }
358                     i_buffer -= i_size;
359                     p_buffer += i_size;
360                 }
361                 /* */
362                 if( p_64_sps && p_64_pps &&
363                     ( asprintf( &rtp_fmt->fmtp,
364                                 "packetization-mode=1;profile-level-id=%s;"
365                                 "sprop-parameter-sets=%s,%s;", hexa, p_64_sps,
366                                 p_64_pps ) == -1 ) )
367                     rtp_fmt->fmtp = NULL;
368                 free( p_64_sps );
369                 free( p_64_pps );
370             }
371             if( rtp_fmt->fmtp == NULL )
372                 rtp_fmt->fmtp = strdup( "packetization-mode=1" );
373             break;
374
375         case VLC_CODEC_MP4V:
376         {
377             rtp_fmt->ptname = "MP4V-ES";
378             rtp_fmt->pf_packetize = rtp_packetize_split;
379             if( p_fmt->i_extra > 0 )
380             {
381                 char hexa[2*p_fmt->i_extra +1];
382                 sprintf_hexa( hexa, p_fmt->p_extra, p_fmt->i_extra );
383                 if( asprintf( &rtp_fmt->fmtp,
384                               "profile-level-id=3; config=%s;", hexa ) == -1 )
385                     rtp_fmt->fmtp = NULL;
386             }
387             break;
388         }
389         case VLC_CODEC_MP4A:
390         {
391             if( ! var_InheritBool( obj, "sout-rtp-mp4a-latm" ) )
392             {
393                 char hexa[2*p_fmt->i_extra +1];
394
395                 rtp_fmt->ptname = "mpeg4-generic";
396                 rtp_fmt->pf_packetize = rtp_packetize_mp4a;
397                 sprintf_hexa( hexa, p_fmt->p_extra, p_fmt->i_extra );
398                 if( asprintf( &rtp_fmt->fmtp,
399                               "streamtype=5; profile-level-id=15; "
400                               "mode=AAC-hbr; config=%s; SizeLength=13; "
401                               "IndexLength=3; IndexDeltaLength=3; Profile=1;",
402                               hexa ) == -1 )
403                     rtp_fmt->fmtp = NULL;
404             }
405             else
406             {
407                 char hexa[13];
408                 int i;
409                 unsigned char config[6];
410                 unsigned int aacsrates[15] = {
411                     96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
412                     16000, 12000, 11025, 8000, 7350, 0, 0 };
413
414                 for( i = 0; i < 15; i++ )
415                     if( p_fmt->audio.i_rate == aacsrates[i] )
416                         break;
417
418                 config[0]=0x40;
419                 config[1]=0;
420                 config[2]=0x20|i;
421                 config[3]=p_fmt->audio.i_channels<<4;
422                 config[4]=0x3f;
423                 config[5]=0xc0;
424
425                 rtp_fmt->ptname = "MP4A-LATM";
426                 rtp_fmt->pf_packetize = rtp_packetize_mp4a_latm;
427                 sprintf_hexa( hexa, config, 6 );
428                 if( asprintf( &rtp_fmt->fmtp, "profile-level-id=15; "
429                               "object=2; cpresent=0; config=%s", hexa ) == -1 )
430                     rtp_fmt->fmtp = NULL;
431             }
432             break;
433         }
434         case VLC_CODEC_AMR_NB:
435             rtp_fmt->ptname = "AMR";
436             rtp_fmt->fmtp = strdup( "octet-align=1" );
437             rtp_fmt->pf_packetize = rtp_packetize_amr;
438             break;
439         case VLC_CODEC_AMR_WB:
440             rtp_fmt->ptname = "AMR-WB";
441             rtp_fmt->fmtp = strdup( "octet-align=1" );
442             rtp_fmt->pf_packetize = rtp_packetize_amr;
443             break;
444         case VLC_CODEC_SPEEX:
445             rtp_fmt->ptname = "SPEEX";
446             rtp_fmt->pf_packetize = rtp_packetize_spx;
447             break;
448         case VLC_CODEC_VORBIS:
449             rtp_fmt->ptname = "vorbis";
450             rtp_fmt->pf_packetize = rtp_packetize_xiph;
451             if( p_fmt->i_extra > 0 )
452             {
453                 rtp_fmt->fmtp = NULL;
454                 char *config = rtp_xiph_b64_oob_config(p_fmt->p_extra,
455                                                        p_fmt->i_extra, NULL);
456                 if (config == NULL)
457                     break;
458                 if( asprintf( &rtp_fmt->fmtp,
459                               "configuration=%s;", config ) == -1 )
460                     rtp_fmt->fmtp = NULL;
461                 free(config);
462             }
463             break;
464         case VLC_CODEC_THEORA:
465             rtp_fmt->ptname = "theora";
466             rtp_fmt->pf_packetize = rtp_packetize_xiph;
467             if( p_fmt->i_extra > 0 )
468             {
469                 rtp_fmt->fmtp = NULL;
470                 uint8_t pixel_fmt, c1, c2;
471                 char *config = rtp_xiph_b64_oob_config(p_fmt->p_extra,
472                                                        p_fmt->i_extra,
473                                                        &pixel_fmt);
474                 if (config == NULL)
475                     break;
476
477                 if (pixel_fmt == 1)
478                 {
479                     /* reserved */
480                     free(config);
481                     break;
482                 }
483                 switch (pixel_fmt)
484                 {
485                     case 0:
486                         c1 = 2;
487                         c2 = 0;
488                         break;
489                     case 2:
490                         c1 = c2 = 2;
491                         break;
492                     case 3:
493                         c1 = c2 = 4;
494                         break;
495                     default:
496                         assert(0);
497                 }
498
499                 if( asprintf( &rtp_fmt->fmtp,
500                               "sampling=YCbCr-4:%d:%d; width=%d; height=%d; "
501                               "delivery-method=inline; configuration=%s; "
502                               "delivery-method=in_band;", c1, c2,
503                               p_fmt->video.i_width, p_fmt->video.i_height,
504                               config ) == -1 )
505                     rtp_fmt->fmtp = NULL;
506                 free(config);
507             }
508             break;
509         case VLC_CODEC_ITU_T140:
510             rtp_fmt->ptname = "t140" ;
511             rtp_fmt->clock_rate = 1000;
512             rtp_fmt->pf_packetize = rtp_packetize_t140;
513             break;
514
515         default:
516             msg_Err( obj, "cannot add this stream (unsupported "
517                      "codec: %4.4s)", (char*)&p_fmt->i_codec );
518             return VLC_EGENERIC;
519     }
520
521     return VLC_SUCCESS;
522 }
523
524
525 static int
526 rtp_packetize_h264_nal( sout_stream_id_t *id,
527                         const uint8_t *p_data, int i_data, int64_t i_pts,
528                         int64_t i_dts, bool b_last, int64_t i_length );
529
530 int rtp_packetize_xiph_config( sout_stream_id_t *id, const char *fmtp,
531                                int64_t i_pts )
532 {
533     if (fmtp == NULL)
534         return VLC_EGENERIC;
535
536     /* extract base64 configuration from fmtp */
537     char *start = strstr(fmtp, "configuration=");
538     assert(start != NULL);
539     start += sizeof("configuration=") - 1;
540     char *end = strchr(start, ';');
541     assert(end != NULL);
542     size_t len = end - start;
543     char b64[len + 1];
544     memcpy(b64, start, len);
545     b64[len] = '\0';
546
547     int     i_max   = rtp_mtu (id) - 6; /* payload max in one packet */
548
549     uint8_t *p_orig, *p_data;
550     int i_data;
551
552     i_data = vlc_b64_decode_binary(&p_orig, b64);
553     if (i_data == 0)
554         return VLC_EGENERIC;
555     assert(i_data > 9);
556     p_data = p_orig + 9;
557     i_data -= 9;
558
559     int i_count = ( i_data + i_max - 1 ) / i_max;
560
561     for( int i = 0; i < i_count; i++ )
562     {
563         int           i_payload = __MIN( i_max, i_data );
564         block_t *out = block_Alloc( 18 + i_payload );
565
566         unsigned fragtype, numpkts;
567         if (i_count == 1)
568         {
569             fragtype = 0;
570             numpkts = 1;
571         }
572         else
573         {
574             numpkts = 0;
575             if (i == 0)
576                 fragtype = 1;
577             else if (i == i_count - 1)
578                 fragtype = 3;
579             else
580                 fragtype = 2;
581         }
582         /* Ident:24, Fragment type:2, Vorbis/Theora Data Type:2, # of pkts:4 */
583         uint32_t header = ((XIPH_IDENT & 0xffffff) << 8) |
584                           (fragtype << 6) | (1 << 4) | numpkts;
585
586         /* rtp common header */
587         rtp_packetize_common( id, out, 0, i_pts );
588
589         SetDWBE( out->p_buffer + 12, header);
590         SetWBE( out->p_buffer + 16, i_payload);
591         memcpy( &out->p_buffer[18], p_data, i_payload );
592
593         out->i_buffer   = 18 + i_payload;
594         out->i_dts    = i_pts;
595
596         rtp_packetize_send( id, out );
597
598         p_data += i_payload;
599         i_data -= i_payload;
600     }
601
602     free(p_orig);
603
604     return VLC_SUCCESS;
605 }
606
607 /* rfc5215 */
608 static int rtp_packetize_xiph( sout_stream_id_t *id, block_t *in )
609 {
610     int     i_max   = rtp_mtu (id) - 6; /* payload max in one packet */
611     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
612
613     uint8_t *p_data = in->p_buffer;
614     int     i_data  = in->i_buffer;
615
616     for( int i = 0; i < i_count; i++ )
617     {
618         int           i_payload = __MIN( i_max, i_data );
619         block_t *out = block_Alloc( 18 + i_payload );
620
621         unsigned fragtype, numpkts;
622         if (i_count == 1)
623         {
624             /* No fragmentation */
625             fragtype = 0;
626             numpkts = 1;
627         }
628         else
629         {
630             /* Fragmentation */
631             numpkts = 0;
632             if (i == 0)
633                 fragtype = 1;
634             else if (i == i_count - 1)
635                 fragtype = 3;
636             else
637                 fragtype = 2;
638         }
639         /* Ident:24, Fragment type:2, Vorbis/Theora Data Type:2, # of pkts:4 */
640         uint32_t header = ((XIPH_IDENT & 0xffffff) << 8) |
641                           (fragtype << 6) | (0 << 4) | numpkts;
642
643         /* rtp common header */
644         rtp_packetize_common( id, out, 0, in->i_pts);
645
646         SetDWBE( out->p_buffer + 12, header);
647         SetWBE( out->p_buffer + 16, i_payload);
648         memcpy( &out->p_buffer[18], p_data, i_payload );
649
650         out->i_buffer   = 18 + i_payload;
651         out->i_dts    = in->i_dts + i * in->i_length / i_count;
652         out->i_length = in->i_length / i_count;
653
654         rtp_packetize_send( id, out );
655
656         p_data += i_payload;
657         i_data -= i_payload;
658     }
659
660     return VLC_SUCCESS;
661 }
662
663 static int rtp_packetize_mpa( sout_stream_id_t *id, block_t *in )
664 {
665     int     i_max   = rtp_mtu (id) - 4; /* payload max in one packet */
666     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
667
668     uint8_t *p_data = in->p_buffer;
669     int     i_data  = in->i_buffer;
670     int     i;
671
672     for( i = 0; i < i_count; i++ )
673     {
674         int           i_payload = __MIN( i_max, i_data );
675         block_t *out = block_Alloc( 16 + i_payload );
676
677         /* rtp common header */
678         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
679         /* mbz set to 0 */
680         SetWBE( out->p_buffer + 12, 0 );
681         /* fragment offset in the current frame */
682         SetWBE( out->p_buffer + 14, i * i_max );
683         memcpy( &out->p_buffer[16], p_data, i_payload );
684
685         out->i_buffer   = 16 + i_payload;
686         out->i_dts    = in->i_dts + i * 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
695     return VLC_SUCCESS;
696 }
697
698 /* rfc2250 */
699 static int rtp_packetize_mpv( sout_stream_id_t *id, block_t *in )
700 {
701     int     i_max   = rtp_mtu (id) - 4; /* payload max in one packet */
702     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
703
704     uint8_t *p_data = in->p_buffer;
705     int     i_data  = in->i_buffer;
706     int     i;
707     int     b_sequence_start = 0;
708     int     i_temporal_ref = 0;
709     int     i_picture_coding_type = 0;
710     int     i_fbv = 0, i_bfc = 0, i_ffv = 0, i_ffc = 0;
711     int     b_start_slice = 0;
712
713     /* preparse this packet to get some info */
714     if( in->i_buffer > 4 )
715     {
716         uint8_t *p = p_data;
717         int      i_rest = in->i_buffer;
718
719         for( ;; )
720         {
721             while( i_rest > 4 &&
722                    ( p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x01 ) )
723             {
724                 p++;
725                 i_rest--;
726             }
727             if( i_rest <= 4 )
728             {
729                 break;
730             }
731             p += 3;
732             i_rest -= 4;
733
734             if( *p == 0xb3 )
735             {
736                 /* sequence start code */
737                 b_sequence_start = 1;
738             }
739             else if( *p == 0x00 && i_rest >= 4 )
740             {
741                 /* picture */
742                 i_temporal_ref = ( p[1] << 2) |((p[2]>>6)&0x03);
743                 i_picture_coding_type = (p[2] >> 3)&0x07;
744
745                 if( i_rest >= 4 && ( i_picture_coding_type == 2 ||
746                                     i_picture_coding_type == 3 ) )
747                 {
748                     i_ffv = (p[3] >> 2)&0x01;
749                     i_ffc = ((p[3]&0x03) << 1)|((p[4]>>7)&0x01);
750                     if( i_rest > 4 && i_picture_coding_type == 3 )
751                     {
752                         i_fbv = (p[4]>>6)&0x01;
753                         i_bfc = (p[4]>>3)&0x07;
754                     }
755                 }
756             }
757             else if( *p <= 0xaf )
758             {
759                 b_start_slice = 1;
760             }
761         }
762     }
763
764     for( i = 0; i < i_count; i++ )
765     {
766         int           i_payload = __MIN( i_max, i_data );
767         block_t *out = block_Alloc( 16 + i_payload );
768         /* 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 */
769         uint32_t      h = ( i_temporal_ref << 16 )|
770                           ( b_sequence_start << 13 )|
771                           ( b_start_slice << 12 )|
772                           ( i == i_count - 1 ? 1 << 11 : 0 )|
773                           ( i_picture_coding_type << 8 )|
774                           ( i_fbv << 7 )|( i_bfc << 4 )|( i_ffv << 3 )|i_ffc;
775
776         /* rtp common header */
777         rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
778                           in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts );
779
780         SetDWBE( out->p_buffer + 12, h );
781
782         memcpy( &out->p_buffer[16], p_data, i_payload );
783
784         out->i_buffer   = 16 + i_payload;
785         out->i_dts    = in->i_dts + i * in->i_length / i_count;
786         out->i_length = in->i_length / i_count;
787
788         rtp_packetize_send( id, out );
789
790         p_data += i_payload;
791         i_data -= i_payload;
792     }
793
794     return VLC_SUCCESS;
795 }
796
797 static int rtp_packetize_ac3( sout_stream_id_t *id, block_t *in )
798 {
799     int     i_max   = rtp_mtu (id) - 2; /* payload max in one packet */
800     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
801
802     uint8_t *p_data = in->p_buffer;
803     int     i_data  = in->i_buffer;
804     int     i;
805
806     for( i = 0; i < i_count; i++ )
807     {
808         int           i_payload = __MIN( i_max, i_data );
809         block_t *out = block_Alloc( 14 + i_payload );
810
811         /* rtp common header */
812         rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
813         /* unit count */
814         out->p_buffer[12] = 1;
815         /* unit header */
816         out->p_buffer[13] = 0x00;
817         /* data */
818         memcpy( &out->p_buffer[14], p_data, i_payload );
819
820         out->i_buffer   = 14 + i_payload;
821         out->i_dts    = in->i_dts + i * in->i_length / i_count;
822         out->i_length = in->i_length / i_count;
823
824         rtp_packetize_send( id, out );
825
826         p_data += i_payload;
827         i_data -= i_payload;
828     }
829
830     return VLC_SUCCESS;
831 }
832
833 static int rtp_packetize_split( sout_stream_id_t *id, block_t *in )
834 {
835     int     i_max   = rtp_mtu (id); /* payload max in one packet */
836     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
837
838     uint8_t *p_data = in->p_buffer;
839     int     i_data  = in->i_buffer;
840     int     i;
841
842     for( i = 0; i < i_count; i++ )
843     {
844         int           i_payload = __MIN( i_max, i_data );
845         block_t *out = block_Alloc( 12 + i_payload );
846
847         /* rtp common header */
848         rtp_packetize_common( id, out, (i == i_count - 1),
849                       (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
850         memcpy( &out->p_buffer[12], p_data, i_payload );
851
852         out->i_buffer   = 12 + i_payload;
853         out->i_dts    = in->i_dts + i * in->i_length / i_count;
854         out->i_length = in->i_length / i_count;
855
856         rtp_packetize_send( id, out );
857
858         p_data += i_payload;
859         i_data -= i_payload;
860     }
861
862     return VLC_SUCCESS;
863 }
864
865 /* split and convert from little endian to network byte order */
866 static int rtp_packetize_swab( sout_stream_id_t *id, block_t *in )
867 {
868     int     i_max   = rtp_mtu (id); /* payload max in one packet */
869     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
870
871     uint8_t *p_data = in->p_buffer;
872     int     i_data  = in->i_buffer;
873     int     i;
874
875     for( i = 0; i < i_count; i++ )
876     {
877         int           i_payload = __MIN( i_max, i_data );
878         block_t *out = block_Alloc( 12 + i_payload );
879
880         /* rtp common header */
881         rtp_packetize_common( id, out, (i == i_count - 1),
882                       (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
883         swab( p_data, out->p_buffer + 12, i_payload );
884
885         out->i_buffer = 12 + i_payload;
886         out->i_dts    = in->i_dts + i * in->i_length / i_count;
887         out->i_length = in->i_length / i_count;
888
889         rtp_packetize_send( id, out );
890
891         p_data += i_payload;
892         i_data -= i_payload;
893     }
894
895     return VLC_SUCCESS;
896 }
897
898 /* rfc3016 */
899 static int rtp_packetize_mp4a_latm( sout_stream_id_t *id, block_t *in )
900 {
901     int     i_max   = rtp_mtu (id) - 2;              /* payload max in one packet */
902     int     latmhdrsize = in->i_buffer / 0xff + 1;
903     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
904
905     uint8_t *p_data = in->p_buffer, *p_header = NULL;
906     int     i_data  = in->i_buffer;
907     int     i;
908
909     for( i = 0; i < i_count; i++ )
910     {
911         int     i_payload = __MIN( i_max, i_data );
912         block_t *out;
913
914         if( i != 0 )
915             latmhdrsize = 0;
916         out = block_Alloc( 12 + latmhdrsize + i_payload );
917
918         /* rtp common header */
919         rtp_packetize_common( id, out, ((i == i_count - 1) ? 1 : 0),
920                       (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
921
922         if( i == 0 )
923         {
924             int tmp = in->i_buffer;
925
926             p_header=out->p_buffer+12;
927             while( tmp > 0xfe )
928             {
929                 *p_header = 0xff;
930                 p_header++;
931                 tmp -= 0xff;
932             }
933             *p_header = tmp;
934         }
935
936         memcpy( &out->p_buffer[12+latmhdrsize], p_data, i_payload );
937
938         out->i_buffer   = 12 + latmhdrsize + i_payload;
939         out->i_dts    = in->i_dts + i * in->i_length / i_count;
940         out->i_length = in->i_length / i_count;
941
942         rtp_packetize_send( id, out );
943
944         p_data += i_payload;
945         i_data -= i_payload;
946     }
947
948     return VLC_SUCCESS;
949 }
950
951 static int rtp_packetize_mp4a( sout_stream_id_t *id, block_t *in )
952 {
953     int     i_max   = rtp_mtu (id) - 4; /* payload max in one packet */
954     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
955
956     uint8_t *p_data = in->p_buffer;
957     int     i_data  = in->i_buffer;
958     int     i;
959
960     for( i = 0; i < i_count; i++ )
961     {
962         int           i_payload = __MIN( i_max, i_data );
963         block_t *out = block_Alloc( 16 + i_payload );
964
965         /* rtp common header */
966         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
967                       (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
968         /* AU headers */
969         /* AU headers length (bits) */
970         out->p_buffer[12] = 0;
971         out->p_buffer[13] = 2*8;
972         /* for each AU length 13 bits + idx 3bits, */
973         SetWBE( out->p_buffer + 14, (in->i_buffer << 3) | 0 );
974
975         memcpy( &out->p_buffer[16], p_data, i_payload );
976
977         out->i_buffer   = 16 + i_payload;
978         out->i_dts    = in->i_dts + i * in->i_length / i_count;
979         out->i_length = in->i_length / i_count;
980
981         rtp_packetize_send( id, out );
982
983         p_data += i_payload;
984         i_data -= i_payload;
985     }
986
987     return VLC_SUCCESS;
988 }
989
990
991 /* rfc2429 */
992 #define RTP_H263_HEADER_SIZE (2)  // plen = 0
993 #define RTP_H263_PAYLOAD_START (14)  // plen = 0
994 static int rtp_packetize_h263( sout_stream_id_t *id, block_t *in )
995 {
996     uint8_t *p_data = in->p_buffer;
997     int     i_data  = in->i_buffer;
998     int     i;
999     int     i_max   = rtp_mtu (id) - RTP_H263_HEADER_SIZE; /* payload max in one packet */
1000     int     i_count;
1001     int     b_p_bit;
1002     int     b_v_bit = 0; // no pesky error resilience
1003     int     i_plen = 0; // normally plen=0 for PSC packet
1004     int     i_pebit = 0; // because plen=0
1005     uint16_t h;
1006
1007     if( i_data < 2 )
1008     {
1009         return VLC_EGENERIC;
1010     }
1011     if( p_data[0] || p_data[1] )
1012     {
1013         return VLC_EGENERIC;
1014     }
1015     /* remove 2 leading 0 bytes */
1016     p_data += 2;
1017     i_data -= 2;
1018     i_count = ( i_data + i_max - 1 ) / i_max;
1019
1020     for( i = 0; i < i_count; i++ )
1021     {
1022         int      i_payload = __MIN( i_max, i_data );
1023         block_t *out = block_Alloc( RTP_H263_PAYLOAD_START + i_payload );
1024         b_p_bit = (i == 0) ? 1 : 0;
1025         h = ( b_p_bit << 10 )|
1026             ( b_v_bit << 9  )|
1027             ( i_plen  << 3  )|
1028               i_pebit;
1029
1030         /* rtp common header */
1031         //b_m_bit = 1; // always contains end of frame
1032         rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
1033                           in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts );
1034
1035         /* h263 header */
1036         SetWBE( out->p_buffer + 12, h );
1037         memcpy( &out->p_buffer[RTP_H263_PAYLOAD_START], p_data, i_payload );
1038
1039         out->i_buffer = RTP_H263_PAYLOAD_START + i_payload;
1040         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1041         out->i_length = in->i_length / i_count;
1042
1043         rtp_packetize_send( id, out );
1044
1045         p_data += i_payload;
1046         i_data -= i_payload;
1047     }
1048
1049     return VLC_SUCCESS;
1050 }
1051
1052 /* rfc3984 */
1053 static int
1054 rtp_packetize_h264_nal( sout_stream_id_t *id,
1055                         const uint8_t *p_data, int i_data, int64_t i_pts,
1056                         int64_t i_dts, bool b_last, int64_t i_length )
1057 {
1058     const int i_max = rtp_mtu (id); /* payload max in one packet */
1059     int i_nal_hdr;
1060     int i_nal_type;
1061
1062     if( i_data < 5 )
1063         return VLC_SUCCESS;
1064
1065     i_nal_hdr = p_data[3];
1066     i_nal_type = i_nal_hdr&0x1f;
1067
1068     /* Skip start code */
1069     p_data += 3;
1070     i_data -= 3;
1071
1072     /* */
1073     if( i_data <= i_max )
1074     {
1075         /* Single NAL unit packet */
1076         block_t *out = block_Alloc( 12 + i_data );
1077         out->i_dts    = i_dts;
1078         out->i_length = i_length;
1079
1080         /* */
1081         rtp_packetize_common( id, out, b_last, i_pts );
1082         out->i_buffer = 12 + i_data;
1083
1084         memcpy( &out->p_buffer[12], p_data, i_data );
1085
1086         rtp_packetize_send( id, out );
1087     }
1088     else
1089     {
1090         /* FU-A Fragmentation Unit without interleaving */
1091         const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2);
1092         int i;
1093
1094         p_data++;
1095         i_data--;
1096
1097         for( i = 0; i < i_count; i++ )
1098         {
1099             const int i_payload = __MIN( i_data, i_max-2 );
1100             block_t *out = block_Alloc( 12 + 2 + i_payload );
1101             out->i_dts    = i_dts + i * i_length / i_count;
1102             out->i_length = i_length / i_count;
1103
1104             /* */
1105             rtp_packetize_common( id, out, (b_last && i_payload == i_data),
1106                                     i_pts );
1107             out->i_buffer = 14 + i_payload;
1108
1109             /* FU indicator */
1110             out->p_buffer[12] = 0x00 | (i_nal_hdr & 0x60) | 28;
1111             /* FU header */
1112             out->p_buffer[13] = ( i == 0 ? 0x80 : 0x00 ) | ( (i == i_count-1) ? 0x40 : 0x00 )  | i_nal_type;
1113             memcpy( &out->p_buffer[14], p_data, i_payload );
1114
1115             rtp_packetize_send( id, out );
1116
1117             i_data -= i_payload;
1118             p_data += i_payload;
1119         }
1120     }
1121     return VLC_SUCCESS;
1122 }
1123
1124 static int rtp_packetize_h264( sout_stream_id_t *id, block_t *in )
1125 {
1126     const uint8_t *p_buffer = in->p_buffer;
1127     int i_buffer = in->i_buffer;
1128
1129     while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] != 1 ) )
1130     {
1131         i_buffer--;
1132         p_buffer++;
1133     }
1134
1135     /* Split nal units */
1136     while( i_buffer > 4 )
1137     {
1138         int i_offset;
1139         int i_size = i_buffer;
1140         int i_skip = i_buffer;
1141
1142         /* search nal end */
1143         for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++)
1144         {
1145             if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 )
1146             {
1147                 /* we found another startcode */
1148                 i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 : 0);
1149                 i_skip = i_offset;
1150                 break;
1151             }
1152         }
1153         /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */
1154         rtp_packetize_h264_nal( id, p_buffer, i_size,
1155                 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts), in->i_dts,
1156                 (i_size >= i_buffer), in->i_length * i_size / in->i_buffer );
1157
1158         i_buffer -= i_skip;
1159         p_buffer += i_skip;
1160     }
1161     return VLC_SUCCESS;
1162 }
1163
1164 static int rtp_packetize_amr( sout_stream_id_t *id, block_t *in )
1165 {
1166     int     i_max   = rtp_mtu (id) - 2; /* payload max in one packet */
1167     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1168
1169     uint8_t *p_data = in->p_buffer;
1170     int     i_data  = in->i_buffer;
1171     int     i;
1172
1173     /* Only supports octet-aligned mode */
1174     for( i = 0; i < i_count; i++ )
1175     {
1176         int           i_payload = __MIN( i_max, i_data );
1177         block_t *out = block_Alloc( 14 + i_payload );
1178
1179         /* rtp common header */
1180         rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
1181                       (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
1182         /* Payload header */
1183         out->p_buffer[12] = 0xF0; /* CMR */
1184         out->p_buffer[13] = p_data[0]&0x7C; /* ToC */ /* FIXME: frame type */
1185
1186         /* FIXME: are we fed multiple frames ? */
1187         memcpy( &out->p_buffer[14], p_data+1, i_payload-1 );
1188
1189         out->i_buffer   = 14 + i_payload-1;
1190         out->i_dts    = in->i_dts + i * in->i_length / i_count;
1191         out->i_length = in->i_length / i_count;
1192
1193         rtp_packetize_send( id, out );
1194
1195         p_data += i_payload;
1196         i_data -= i_payload;
1197     }
1198
1199     return VLC_SUCCESS;
1200 }
1201
1202 static int rtp_packetize_t140( sout_stream_id_t *id, block_t *in )
1203 {
1204     const size_t   i_max  = rtp_mtu (id);
1205     const uint8_t *p_data = in->p_buffer;
1206     size_t         i_data = in->i_buffer;
1207
1208     for( unsigned i_packet = 0; i_data > 0; i_packet++ )
1209     {
1210         size_t i_payload = i_data;
1211
1212         /* Make sure we stop on an UTF-8 character boundary
1213          * (assuming the input is valid UTF-8) */
1214         if( i_data > i_max )
1215         {
1216             i_payload = i_max;
1217
1218             while( ( p_data[i_payload] & 0xC0 ) == 0x80 )
1219             {
1220                 if( i_payload == 0 )
1221                     return VLC_SUCCESS; /* fishy input! */
1222
1223                 i_payload--;
1224             }
1225         }
1226
1227         block_t *out = block_Alloc( 12 + i_payload );
1228         if( out == NULL )
1229             return VLC_SUCCESS;
1230
1231         rtp_packetize_common( id, out, 0, in->i_pts + i_packet );
1232         memcpy( out->p_buffer + 12, p_data, i_payload );
1233
1234         out->i_buffer = 12 + i_payload;
1235         out->i_dts    = in->i_pts;
1236         out->i_length = 0;
1237
1238         rtp_packetize_send( id, out );
1239
1240         p_data += i_payload;
1241         i_data -= i_payload;
1242     }
1243
1244     return VLC_SUCCESS;
1245 }
1246
1247
1248 static int rtp_packetize_spx( sout_stream_id_t *id, block_t *in )
1249 {
1250     uint8_t *p_buffer = in->p_buffer;
1251     int i_data_size, i_payload_size, i_payload_padding;
1252     i_data_size = i_payload_size = in->i_buffer;
1253     i_payload_padding = 0;
1254     block_t *p_out;
1255
1256     if ( in->i_buffer > rtp_mtu (id) )
1257         return VLC_SUCCESS;
1258
1259     /*
1260       RFC for Speex in RTP says that each packet must end on an octet 
1261       boundary. So, we check to see if the number of bytes % 4 is zero.
1262       If not, we have to add some padding. 
1263
1264       This MAY be overkill since packetization is handled elsewhere and 
1265       appears to ensure the octet boundary. However, better safe than
1266       sorry.
1267     */
1268     if ( i_payload_size % 4 )
1269     {
1270         i_payload_padding = 4 - ( i_payload_size % 4 );
1271         i_payload_size += i_payload_padding;
1272     }
1273
1274     /*
1275       Allocate a new RTP p_output block of the appropriate size. 
1276       Allow for 12 extra bytes of RTP header. 
1277     */
1278     p_out = block_Alloc( 12 + i_payload_size );
1279
1280     if ( i_payload_padding )
1281     {
1282     /*
1283       The padding is required to be a zero followed by all 1s.
1284     */
1285         char c_first_pad, c_remaining_pad;
1286         c_first_pad = 0x7F;
1287         c_remaining_pad = 0xFF;
1288
1289         /*
1290           Allow for 12 bytes before the i_data_size because
1291           of the expected RTP header added during
1292           rtp_packetize_common.
1293         */
1294         p_out->p_buffer[12 + i_data_size] = c_first_pad; 
1295         switch (i_payload_padding)
1296         {
1297           case 2:
1298             p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad; 
1299             break;
1300           case 3:
1301             p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad; 
1302             p_out->p_buffer[12 + i_data_size + 2] = c_remaining_pad; 
1303             break;
1304         }
1305     }
1306
1307     /* Add the RTP header to our p_output buffer. */
1308     rtp_packetize_common( id, p_out, 0,
1309                         (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
1310     /* Copy the Speex payload to the p_output buffer */
1311     memcpy( &p_out->p_buffer[12], p_buffer, i_data_size );
1312
1313     p_out->i_buffer = 12 + i_payload_size;
1314     p_out->i_dts = in->i_dts;
1315     p_out->i_length = in->i_length;
1316
1317     /* Queue the buffer for actual transmission. */
1318     rtp_packetize_send( id, p_out );
1319     return VLC_SUCCESS;
1320 }
1321
1322 static int rtp_packetize_g726( sout_stream_id_t *id, block_t *in, int i_pad )
1323 {
1324     int     i_max   = (rtp_mtu( id )- 12 + i_pad - 1) & ~i_pad;
1325     int     i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1326
1327     uint8_t *p_data = in->p_buffer;
1328     int     i_data  = in->i_buffer;
1329     int     i_packet = 0;
1330
1331     while( i_data > 0 )
1332     {
1333         int           i_payload = __MIN( i_max, i_data );
1334         block_t *out = block_Alloc( 12 + i_payload );
1335
1336         /* rtp common header */
1337         rtp_packetize_common( id, out, 0,
1338                       (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
1339
1340         memcpy( &out->p_buffer[12], p_data, i_payload );
1341
1342         out->i_buffer   = 12 + i_payload;
1343         out->i_dts    = in->i_dts + i_packet++ * in->i_length / i_count;
1344         out->i_length = in->i_length / i_count;
1345
1346         rtp_packetize_send( id, out );
1347
1348         p_data += i_payload;
1349         i_data -= i_payload;
1350     }
1351     return VLC_SUCCESS;
1352 }
1353
1354 static int rtp_packetize_g726_16( sout_stream_id_t *id, block_t *in )
1355 {
1356     return rtp_packetize_g726( id, in, 4 );
1357 }
1358
1359 static int rtp_packetize_g726_24( sout_stream_id_t *id, block_t *in )
1360 {
1361     return rtp_packetize_g726( id, in, 8 );
1362 }
1363
1364 static int rtp_packetize_g726_32( sout_stream_id_t *id, block_t *in )
1365 {
1366     return rtp_packetize_g726( id, in, 2 );
1367 }
1368
1369 static int rtp_packetize_g726_40( sout_stream_id_t *id, block_t *in )
1370 {
1371     return rtp_packetize_g726( id, in, 8 );
1372 }