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