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