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