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