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