Dash: major warnings cleanup
[vlc.git] / modules / stream_out / rtpfmt.c
blob79ae441226552ef486d410b82513bf8767596edb
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$
8 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
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.
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.
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 *****************************************************************************/
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
29 #include <vlc_common.h>
30 #include <vlc_sout.h>
31 #include <vlc_block.h>
32 #include <vlc_strings.h>
34 #include "rtp.h"
35 #include "../demux/xiph.h"
37 #include <assert.h>
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 *);
57 #define XIPH_IDENT (0)
59 /* Helpers common to xiph codecs (vorbis and theora) */
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)
65 unsigned packet_size[XIPH_MAX_HEADER_COUNT];
66 void *packet[XIPH_MAX_HEADER_COUNT];
67 unsigned packet_count;
68 int val = xiph_SplitHeaders(packet_size, packet, &packet_count,
69 i_extra, p_extra);
70 if (val != VLC_SUCCESS)
71 return val;
72 if (packet_count < 3)
74 val = VLC_EGENERIC;
75 goto free;
78 if (theora_pixel_fmt != NULL)
80 if (packet_size[0] < 42)
82 val = VLC_EGENERIC;
83 goto free;
85 *theora_pixel_fmt = (((uint8_t *)packet[0])[41] >> 3) & 0x03;
88 unsigned length_size[2] = { 0, 0 };
89 for (int i = 0; i < 2; i++)
91 unsigned size = packet_size[i];
92 while (size > 0)
94 length_size[i]++;
95 size >>= 7;
99 *i_buffer = room + 1 + length_size[0] + length_size[1]
100 + packet_size[0] + packet_size[1] + packet_size[2];
101 *p_buffer = malloc(*i_buffer);
102 if (*p_buffer == NULL)
104 val = VLC_ENOMEM;
105 goto free;
108 uint8_t *p = *p_buffer + room;
109 /* Number of headers */
110 *p++ = 2;
112 for (int i = 0; i < 2; i++)
114 unsigned size = length_size[i];
115 while (size > 0)
117 *p = (packet_size[i] >> (7 * (size - 1))) & 0x7f;
118 if (--size > 0)
119 *p |= 0x80;
120 p++;
123 for (int i = 0; i < 3; i++)
125 memcpy(p, packet[i], packet_size[i]);
126 p += packet_size[i];
129 val = VLC_SUCCESS;
130 free:
131 for (unsigned i = 0; i < packet_count; i++)
132 free(packet[i]);
134 return val;
137 static char *rtp_xiph_b64_oob_config(void *p_extra, size_t i_extra,
138 uint8_t *theora_pixel_fmt)
140 uint8_t *p_buffer;
141 size_t i_buffer;
142 if (rtp_xiph_pack_headers(9, p_extra, i_extra, &p_buffer, &i_buffer,
143 theora_pixel_fmt) != VLC_SUCCESS)
144 return NULL;
146 /* Number of packed headers */
147 SetDWBE(p_buffer, 1);
148 /* Ident */
149 uint32_t ident = XIPH_IDENT;
150 SetWBE(p_buffer + 4, ident >> 8);
151 p_buffer[6] = ident & 0xff;
152 /* Length field */
153 SetWBE(p_buffer + 7, i_buffer);
155 char *config = vlc_b64_encode_binary(p_buffer, i_buffer);
156 free(p_buffer);
157 return config;
160 static void sprintf_hexa( char *s, uint8_t *p_data, int i_data )
162 static const char hex[16] = "0123456789abcdef";
164 for( int i = 0; i < i_data; i++ )
166 s[2*i+0] = hex[(p_data[i]>>4)&0xf];
167 s[2*i+1] = hex[(p_data[i] )&0xf];
169 s[2*i_data] = '\0';
172 /* TODO: make this into something more clever than a big switch? */
173 int rtp_get_fmt( vlc_object_t *obj, es_format_t *p_fmt, const char *mux,
174 rtp_format_t *rtp_fmt )
176 assert( p_fmt != NULL || mux != NULL );
178 /* Dynamic payload type. Payload types are scoped to the RTP
179 * session, and we put each ES in its own session, so no risk of
180 * conflict. */
181 rtp_fmt->payload_type = 96;
182 rtp_fmt->cat = mux != NULL ? VIDEO_ES : p_fmt->i_cat;
183 if( rtp_fmt->cat == AUDIO_ES )
185 rtp_fmt->clock_rate = p_fmt->audio.i_rate;
186 rtp_fmt->channels = p_fmt->audio.i_channels;
188 else
189 rtp_fmt->clock_rate = 90000; /* most common case for video */
190 /* Stream bitrate in kbps */
191 rtp_fmt->bitrate = p_fmt != NULL ? p_fmt->i_bitrate/1000 : 0;
192 rtp_fmt->fmtp = NULL;
194 if( mux != NULL )
196 if( strncmp( mux, "ts", 2 ) == 0 )
198 rtp_fmt->payload_type = 33;
199 rtp_fmt->ptname = "MP2T";
201 else
202 rtp_fmt->ptname = "MP2P";
203 return VLC_SUCCESS;
206 switch( p_fmt->i_codec )
208 case VLC_CODEC_MULAW:
209 if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
210 rtp_fmt->payload_type = 0;
211 rtp_fmt->ptname = "PCMU";
212 rtp_fmt->pf_packetize = rtp_packetize_split;
213 break;
214 case VLC_CODEC_ALAW:
215 if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
216 rtp_fmt->payload_type = 8;
217 rtp_fmt->ptname = "PCMA";
218 rtp_fmt->pf_packetize = rtp_packetize_split;
219 break;
220 case VLC_CODEC_S16B:
221 case VLC_CODEC_S16L:
222 if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 44100 )
224 rtp_fmt->payload_type = 11;
226 else if( p_fmt->audio.i_channels == 2 &&
227 p_fmt->audio.i_rate == 44100 )
229 rtp_fmt->payload_type = 10;
231 rtp_fmt->ptname = "L16";
232 if( p_fmt->i_codec == VLC_CODEC_S16B )
233 rtp_fmt->pf_packetize = rtp_packetize_split;
234 else
235 rtp_fmt->pf_packetize = rtp_packetize_swab;
236 break;
237 case VLC_CODEC_U8:
238 rtp_fmt->ptname = "L8";
239 rtp_fmt->pf_packetize = rtp_packetize_split;
240 break;
241 case VLC_CODEC_S24B:
242 rtp_fmt->ptname = "L24";
243 rtp_fmt->pf_packetize = rtp_packetize_split;
244 break;
245 case VLC_CODEC_MPGA:
246 rtp_fmt->payload_type = 14;
247 rtp_fmt->ptname = "MPA";
248 rtp_fmt->clock_rate = 90000; /* not 44100 */
249 rtp_fmt->pf_packetize = rtp_packetize_mpa;
250 break;
251 case VLC_CODEC_MPGV:
252 rtp_fmt->payload_type = 32;
253 rtp_fmt->ptname = "MPV";
254 rtp_fmt->pf_packetize = rtp_packetize_mpv;
255 break;
256 case VLC_CODEC_ADPCM_G726:
257 switch( p_fmt->i_bitrate / 1000 )
259 case 16:
260 rtp_fmt->ptname = "G726-16";
261 rtp_fmt->pf_packetize = rtp_packetize_g726_16;
262 break;
263 case 24:
264 rtp_fmt->ptname = "G726-24";
265 rtp_fmt->pf_packetize = rtp_packetize_g726_24;
266 break;
267 case 32:
268 rtp_fmt->ptname = "G726-32";
269 rtp_fmt->pf_packetize = rtp_packetize_g726_32;
270 break;
271 case 40:
272 rtp_fmt->ptname = "G726-40";
273 rtp_fmt->pf_packetize = rtp_packetize_g726_40;
274 break;
275 default:
276 msg_Err( obj, "cannot add this stream (unsupported "
277 "G.726 bit rate: %u)", p_fmt->i_bitrate );
278 return VLC_EGENERIC;
280 break;
281 case VLC_CODEC_A52:
282 rtp_fmt->ptname = "ac3";
283 rtp_fmt->pf_packetize = rtp_packetize_ac3;
284 break;
285 case VLC_CODEC_H263:
286 rtp_fmt->ptname = "H263-1998";
287 rtp_fmt->pf_packetize = rtp_packetize_h263;
288 break;
289 case VLC_CODEC_H264:
290 rtp_fmt->ptname = "H264";
291 rtp_fmt->pf_packetize = rtp_packetize_h264;
292 rtp_fmt->fmtp = NULL;
294 if( p_fmt->i_extra > 0 )
296 uint8_t *p_buffer = p_fmt->p_extra;
297 int i_buffer = p_fmt->i_extra;
298 char *p_64_sps = NULL;
299 char *p_64_pps = NULL;
300 char hexa[6+1];
302 while( i_buffer > 4 )
304 int i_offset = 0;
305 int i_size = 0;
307 while( p_buffer[0] != 0 || p_buffer[1] != 0 ||
308 p_buffer[2] != 1 )
310 p_buffer++;
311 i_buffer--;
312 if( i_buffer == 0 ) break;
315 if( i_buffer < 4 || memcmp(p_buffer, "\x00\x00\x01", 3 ) )
317 msg_Dbg( obj, "No startcode found..");
318 break;
320 p_buffer += 3;
321 i_buffer -= 3;
323 const int i_nal_type = p_buffer[0]&0x1f;
325 msg_Dbg( obj, "we found a startcode for NAL with TYPE:%d", i_nal_type );
327 i_size = i_buffer;
328 for( i_offset = 0; i_offset+2 < i_buffer ; i_offset++)
330 if( !memcmp(p_buffer + i_offset, "\x00\x00\x01", 3 ) )
332 /* we found another startcode */
333 while( i_offset > 0 && 0 == p_buffer[ i_offset - 1 ] )
334 i_offset--;
335 i_size = i_offset;
336 break;
340 if( i_size == 0 )
342 msg_Dbg( obj, "No-info found in nal ");
343 continue;
346 if( i_nal_type == 7 )
348 free( p_64_sps );
349 p_64_sps = vlc_b64_encode_binary( p_buffer, i_size );
350 /* XXX: nothing ensures that i_size >= 4 ?? */
351 sprintf_hexa( hexa, &p_buffer[1], 3 );
353 else if( i_nal_type == 8 )
355 free( p_64_pps );
356 p_64_pps = vlc_b64_encode_binary( p_buffer, i_size );
358 i_buffer -= i_size;
359 p_buffer += i_size;
361 /* */
362 if( p_64_sps && p_64_pps &&
363 ( asprintf( &rtp_fmt->fmtp,
364 "packetization-mode=1;profile-level-id=%s;"
365 "sprop-parameter-sets=%s,%s;", hexa, p_64_sps,
366 p_64_pps ) == -1 ) )
367 rtp_fmt->fmtp = NULL;
368 free( p_64_sps );
369 free( p_64_pps );
371 if( rtp_fmt->fmtp == NULL )
372 rtp_fmt->fmtp = strdup( "packetization-mode=1" );
373 break;
375 case VLC_CODEC_MP4V:
377 rtp_fmt->ptname = "MP4V-ES";
378 rtp_fmt->pf_packetize = rtp_packetize_split;
379 if( p_fmt->i_extra > 0 )
381 char hexa[2*p_fmt->i_extra +1];
382 sprintf_hexa( hexa, p_fmt->p_extra, p_fmt->i_extra );
383 if( asprintf( &rtp_fmt->fmtp,
384 "profile-level-id=3; config=%s;", hexa ) == -1 )
385 rtp_fmt->fmtp = NULL;
387 break;
389 case VLC_CODEC_MP4A:
391 if( ! var_InheritBool( obj, "sout-rtp-mp4a-latm" ) )
393 char hexa[2*p_fmt->i_extra +1];
395 rtp_fmt->ptname = "mpeg4-generic";
396 rtp_fmt->pf_packetize = rtp_packetize_mp4a;
397 sprintf_hexa( hexa, p_fmt->p_extra, p_fmt->i_extra );
398 if( asprintf( &rtp_fmt->fmtp,
399 "streamtype=5; profile-level-id=15; "
400 "mode=AAC-hbr; config=%s; SizeLength=13; "
401 "IndexLength=3; IndexDeltaLength=3; Profile=1;",
402 hexa ) == -1 )
403 rtp_fmt->fmtp = NULL;
405 else
407 char hexa[13];
408 int i;
409 unsigned char config[6];
410 unsigned int aacsrates[15] = {
411 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
412 16000, 12000, 11025, 8000, 7350, 0, 0 };
414 for( i = 0; i < 15; i++ )
415 if( p_fmt->audio.i_rate == aacsrates[i] )
416 break;
418 config[0]=0x40;
419 config[1]=0;
420 config[2]=0x20|i;
421 config[3]=p_fmt->audio.i_channels<<4;
422 config[4]=0x3f;
423 config[5]=0xc0;
425 rtp_fmt->ptname = "MP4A-LATM";
426 rtp_fmt->pf_packetize = rtp_packetize_mp4a_latm;
427 sprintf_hexa( hexa, config, 6 );
428 if( asprintf( &rtp_fmt->fmtp, "profile-level-id=15; "
429 "object=2; cpresent=0; config=%s", hexa ) == -1 )
430 rtp_fmt->fmtp = NULL;
432 break;
434 case VLC_CODEC_AMR_NB:
435 rtp_fmt->ptname = "AMR";
436 rtp_fmt->fmtp = strdup( "octet-align=1" );
437 rtp_fmt->pf_packetize = rtp_packetize_amr;
438 break;
439 case VLC_CODEC_AMR_WB:
440 rtp_fmt->ptname = "AMR-WB";
441 rtp_fmt->fmtp = strdup( "octet-align=1" );
442 rtp_fmt->pf_packetize = rtp_packetize_amr;
443 break;
444 case VLC_CODEC_SPEEX:
445 rtp_fmt->ptname = "SPEEX";
446 rtp_fmt->pf_packetize = rtp_packetize_spx;
447 break;
448 case VLC_CODEC_VORBIS:
449 rtp_fmt->ptname = "vorbis";
450 rtp_fmt->pf_packetize = rtp_packetize_xiph;
451 if( p_fmt->i_extra > 0 )
453 rtp_fmt->fmtp = NULL;
454 char *config = rtp_xiph_b64_oob_config(p_fmt->p_extra,
455 p_fmt->i_extra, NULL);
456 if (config == NULL)
457 break;
458 if( asprintf( &rtp_fmt->fmtp,
459 "configuration=%s;", config ) == -1 )
460 rtp_fmt->fmtp = NULL;
461 free(config);
463 break;
464 case VLC_CODEC_THEORA:
465 rtp_fmt->ptname = "theora";
466 rtp_fmt->pf_packetize = rtp_packetize_xiph;
467 if( p_fmt->i_extra > 0 )
469 rtp_fmt->fmtp = NULL;
470 uint8_t pixel_fmt, c1, c2;
471 char *config = rtp_xiph_b64_oob_config(p_fmt->p_extra,
472 p_fmt->i_extra,
473 &pixel_fmt);
474 if (config == NULL)
475 break;
477 if (pixel_fmt == 1)
479 /* reserved */
480 free(config);
481 break;
483 switch (pixel_fmt)
485 case 0:
486 c1 = 2;
487 c2 = 0;
488 break;
489 case 2:
490 c1 = c2 = 2;
491 break;
492 case 3:
493 c1 = c2 = 4;
494 break;
495 default:
496 assert(0);
499 if( asprintf( &rtp_fmt->fmtp,
500 "sampling=YCbCr-4:%d:%d; width=%d; height=%d; "
501 "delivery-method=inline; configuration=%s; "
502 "delivery-method=in_band;", c1, c2,
503 p_fmt->video.i_width, p_fmt->video.i_height,
504 config ) == -1 )
505 rtp_fmt->fmtp = NULL;
506 free(config);
508 break;
509 case VLC_CODEC_ITU_T140:
510 rtp_fmt->ptname = "t140" ;
511 rtp_fmt->clock_rate = 1000;
512 rtp_fmt->pf_packetize = rtp_packetize_t140;
513 break;
515 default:
516 msg_Err( obj, "cannot add this stream (unsupported "
517 "codec: %4.4s)", (char*)&p_fmt->i_codec );
518 return VLC_EGENERIC;
521 return VLC_SUCCESS;
525 static int
526 rtp_packetize_h264_nal( sout_stream_id_t *id,
527 const uint8_t *p_data, int i_data, int64_t i_pts,
528 int64_t i_dts, bool b_last, int64_t i_length );
530 int rtp_packetize_xiph_config( sout_stream_id_t *id, const char *fmtp,
531 int64_t i_pts )
533 if (fmtp == NULL)
534 return VLC_EGENERIC;
536 /* extract base64 configuration from fmtp */
537 char *start = strstr(fmtp, "configuration=");
538 assert(start != NULL);
539 start += sizeof("configuration=") - 1;
540 char *end = strchr(start, ';');
541 assert(end != NULL);
542 size_t len = end - start;
543 char b64[len + 1];
544 memcpy(b64, start, len);
545 b64[len] = '\0';
547 int i_max = rtp_mtu (id) - 6; /* payload max in one packet */
549 uint8_t *p_orig, *p_data;
550 int i_data;
552 i_data = vlc_b64_decode_binary(&p_orig, b64);
553 if (i_data == 0)
554 return VLC_EGENERIC;
555 assert(i_data > 9);
556 p_data = p_orig + 9;
557 i_data -= 9;
559 int i_count = ( i_data + i_max - 1 ) / i_max;
561 for( int i = 0; i < i_count; i++ )
563 int i_payload = __MIN( i_max, i_data );
564 block_t *out = block_Alloc( 18 + i_payload );
566 unsigned fragtype, numpkts;
567 if (i_count == 1)
569 fragtype = 0;
570 numpkts = 1;
572 else
574 numpkts = 0;
575 if (i == 0)
576 fragtype = 1;
577 else if (i == i_count - 1)
578 fragtype = 3;
579 else
580 fragtype = 2;
582 /* Ident:24, Fragment type:2, Vorbis/Theora Data Type:2, # of pkts:4 */
583 uint32_t header = ((XIPH_IDENT & 0xffffff) << 8) |
584 (fragtype << 6) | (1 << 4) | numpkts;
586 /* rtp common header */
587 rtp_packetize_common( id, out, 0, i_pts );
589 SetDWBE( out->p_buffer + 12, header);
590 SetWBE( out->p_buffer + 16, i_payload);
591 memcpy( &out->p_buffer[18], p_data, i_payload );
593 out->i_buffer = 18 + i_payload;
594 out->i_dts = i_pts;
596 rtp_packetize_send( id, out );
598 p_data += i_payload;
599 i_data -= i_payload;
602 free(p_orig);
604 return VLC_SUCCESS;
607 /* rfc5215 */
608 static int rtp_packetize_xiph( sout_stream_id_t *id, block_t *in )
610 int i_max = rtp_mtu (id) - 6; /* payload max in one packet */
611 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
613 uint8_t *p_data = in->p_buffer;
614 int i_data = in->i_buffer;
616 for( int i = 0; i < i_count; i++ )
618 int i_payload = __MIN( i_max, i_data );
619 block_t *out = block_Alloc( 18 + i_payload );
621 unsigned fragtype, numpkts;
622 if (i_count == 1)
624 /* No fragmentation */
625 fragtype = 0;
626 numpkts = 1;
628 else
630 /* Fragmentation */
631 numpkts = 0;
632 if (i == 0)
633 fragtype = 1;
634 else if (i == i_count - 1)
635 fragtype = 3;
636 else
637 fragtype = 2;
639 /* Ident:24, Fragment type:2, Vorbis/Theora Data Type:2, # of pkts:4 */
640 uint32_t header = ((XIPH_IDENT & 0xffffff) << 8) |
641 (fragtype << 6) | (0 << 4) | numpkts;
643 /* rtp common header */
644 rtp_packetize_common( id, out, 0, in->i_pts);
646 SetDWBE( out->p_buffer + 12, header);
647 SetWBE( out->p_buffer + 16, i_payload);
648 memcpy( &out->p_buffer[18], p_data, i_payload );
650 out->i_buffer = 18 + i_payload;
651 out->i_dts = in->i_dts + i * in->i_length / i_count;
652 out->i_length = in->i_length / i_count;
654 rtp_packetize_send( id, out );
656 p_data += i_payload;
657 i_data -= i_payload;
660 return VLC_SUCCESS;
663 static int rtp_packetize_mpa( sout_stream_id_t *id, block_t *in )
665 int i_max = rtp_mtu (id) - 4; /* payload max in one packet */
666 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
668 uint8_t *p_data = in->p_buffer;
669 int i_data = in->i_buffer;
670 int i;
672 for( i = 0; i < i_count; i++ )
674 int i_payload = __MIN( i_max, i_data );
675 block_t *out = block_Alloc( 16 + i_payload );
677 /* rtp common header */
678 rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
679 /* mbz set to 0 */
680 SetWBE( out->p_buffer + 12, 0 );
681 /* fragment offset in the current frame */
682 SetWBE( out->p_buffer + 14, i * i_max );
683 memcpy( &out->p_buffer[16], p_data, i_payload );
685 out->i_buffer = 16 + i_payload;
686 out->i_dts = in->i_dts + i * in->i_length / i_count;
687 out->i_length = in->i_length / i_count;
689 rtp_packetize_send( id, out );
691 p_data += i_payload;
692 i_data -= i_payload;
695 return VLC_SUCCESS;
698 /* rfc2250 */
699 static int rtp_packetize_mpv( sout_stream_id_t *id, block_t *in )
701 int i_max = rtp_mtu (id) - 4; /* payload max in one packet */
702 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
704 uint8_t *p_data = in->p_buffer;
705 int i_data = in->i_buffer;
706 int i;
707 int b_sequence_start = 0;
708 int i_temporal_ref = 0;
709 int i_picture_coding_type = 0;
710 int i_fbv = 0, i_bfc = 0, i_ffv = 0, i_ffc = 0;
711 int b_start_slice = 0;
713 /* preparse this packet to get some info */
714 if( in->i_buffer > 4 )
716 uint8_t *p = p_data;
717 int i_rest = in->i_buffer;
719 for( ;; )
721 while( i_rest > 4 &&
722 ( p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x01 ) )
724 p++;
725 i_rest--;
727 if( i_rest <= 4 )
729 break;
731 p += 3;
732 i_rest -= 4;
734 if( *p == 0xb3 )
736 /* sequence start code */
737 b_sequence_start = 1;
739 else if( *p == 0x00 && i_rest >= 4 )
741 /* picture */
742 i_temporal_ref = ( p[1] << 2) |((p[2]>>6)&0x03);
743 i_picture_coding_type = (p[2] >> 3)&0x07;
745 if( i_rest >= 4 && ( i_picture_coding_type == 2 ||
746 i_picture_coding_type == 3 ) )
748 i_ffv = (p[3] >> 2)&0x01;
749 i_ffc = ((p[3]&0x03) << 1)|((p[4]>>7)&0x01);
750 if( i_rest > 4 && i_picture_coding_type == 3 )
752 i_fbv = (p[4]>>6)&0x01;
753 i_bfc = (p[4]>>3)&0x07;
757 else if( *p <= 0xaf )
759 b_start_slice = 1;
764 for( i = 0; i < i_count; i++ )
766 int i_payload = __MIN( i_max, i_data );
767 block_t *out = block_Alloc( 16 + i_payload );
768 /* 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 */
769 uint32_t h = ( i_temporal_ref << 16 )|
770 ( b_sequence_start << 13 )|
771 ( b_start_slice << 12 )|
772 ( i == i_count - 1 ? 1 << 11 : 0 )|
773 ( i_picture_coding_type << 8 )|
774 ( i_fbv << 7 )|( i_bfc << 4 )|( i_ffv << 3 )|i_ffc;
776 /* rtp common header */
777 rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
778 in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts );
780 SetDWBE( out->p_buffer + 12, h );
782 memcpy( &out->p_buffer[16], p_data, i_payload );
784 out->i_buffer = 16 + i_payload;
785 out->i_dts = in->i_dts + i * in->i_length / i_count;
786 out->i_length = in->i_length / i_count;
788 rtp_packetize_send( id, out );
790 p_data += i_payload;
791 i_data -= i_payload;
794 return VLC_SUCCESS;
797 static int rtp_packetize_ac3( sout_stream_id_t *id, block_t *in )
799 int i_max = rtp_mtu (id) - 2; /* payload max in one packet */
800 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
802 uint8_t *p_data = in->p_buffer;
803 int i_data = in->i_buffer;
804 int i;
806 for( i = 0; i < i_count; i++ )
808 int i_payload = __MIN( i_max, i_data );
809 block_t *out = block_Alloc( 14 + i_payload );
811 /* rtp common header */
812 rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
813 /* unit count */
814 out->p_buffer[12] = 1;
815 /* unit header */
816 out->p_buffer[13] = 0x00;
817 /* data */
818 memcpy( &out->p_buffer[14], p_data, i_payload );
820 out->i_buffer = 14 + i_payload;
821 out->i_dts = in->i_dts + i * in->i_length / i_count;
822 out->i_length = in->i_length / i_count;
824 rtp_packetize_send( id, out );
826 p_data += i_payload;
827 i_data -= i_payload;
830 return VLC_SUCCESS;
833 static int rtp_packetize_split( sout_stream_id_t *id, block_t *in )
835 int i_max = rtp_mtu (id); /* payload max in one packet */
836 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
838 uint8_t *p_data = in->p_buffer;
839 int i_data = in->i_buffer;
840 int i;
842 for( i = 0; i < i_count; i++ )
844 int i_payload = __MIN( i_max, i_data );
845 block_t *out = block_Alloc( 12 + i_payload );
847 /* rtp common header */
848 rtp_packetize_common( id, out, (i == i_count - 1),
849 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
850 memcpy( &out->p_buffer[12], p_data, i_payload );
852 out->i_buffer = 12 + i_payload;
853 out->i_dts = in->i_dts + i * in->i_length / i_count;
854 out->i_length = in->i_length / i_count;
856 rtp_packetize_send( id, out );
858 p_data += i_payload;
859 i_data -= i_payload;
862 return VLC_SUCCESS;
865 /* split and convert from little endian to network byte order */
866 static int rtp_packetize_swab( sout_stream_id_t *id, block_t *in )
868 int i_max = rtp_mtu (id); /* payload max in one packet */
869 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
871 uint8_t *p_data = in->p_buffer;
872 int i_data = in->i_buffer;
873 int i;
875 for( i = 0; i < i_count; i++ )
877 int i_payload = __MIN( i_max, i_data );
878 block_t *out = block_Alloc( 12 + i_payload );
880 /* rtp common header */
881 rtp_packetize_common( id, out, (i == i_count - 1),
882 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
883 swab( p_data, out->p_buffer + 12, i_payload );
885 out->i_buffer = 12 + i_payload;
886 out->i_dts = in->i_dts + i * in->i_length / i_count;
887 out->i_length = in->i_length / i_count;
889 rtp_packetize_send( id, out );
891 p_data += i_payload;
892 i_data -= i_payload;
895 return VLC_SUCCESS;
898 /* rfc3016 */
899 static int rtp_packetize_mp4a_latm( sout_stream_id_t *id, block_t *in )
901 int i_max = rtp_mtu (id) - 2; /* payload max in one packet */
902 int latmhdrsize = in->i_buffer / 0xff + 1;
903 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
905 uint8_t *p_data = in->p_buffer, *p_header = NULL;
906 int i_data = in->i_buffer;
907 int i;
909 for( i = 0; i < i_count; i++ )
911 int i_payload = __MIN( i_max, i_data );
912 block_t *out;
914 if( i != 0 )
915 latmhdrsize = 0;
916 out = block_Alloc( 12 + latmhdrsize + i_payload );
918 /* rtp common header */
919 rtp_packetize_common( id, out, ((i == i_count - 1) ? 1 : 0),
920 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
922 if( i == 0 )
924 int tmp = in->i_buffer;
926 p_header=out->p_buffer+12;
927 while( tmp > 0xfe )
929 *p_header = 0xff;
930 p_header++;
931 tmp -= 0xff;
933 *p_header = tmp;
936 memcpy( &out->p_buffer[12+latmhdrsize], p_data, i_payload );
938 out->i_buffer = 12 + latmhdrsize + i_payload;
939 out->i_dts = in->i_dts + i * in->i_length / i_count;
940 out->i_length = in->i_length / i_count;
942 rtp_packetize_send( id, out );
944 p_data += i_payload;
945 i_data -= i_payload;
948 return VLC_SUCCESS;
951 static int rtp_packetize_mp4a( sout_stream_id_t *id, block_t *in )
953 int i_max = rtp_mtu (id) - 4; /* payload max in one packet */
954 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
956 uint8_t *p_data = in->p_buffer;
957 int i_data = in->i_buffer;
958 int i;
960 for( i = 0; i < i_count; i++ )
962 int i_payload = __MIN( i_max, i_data );
963 block_t *out = block_Alloc( 16 + i_payload );
965 /* rtp common header */
966 rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
967 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
968 /* AU headers */
969 /* AU headers length (bits) */
970 out->p_buffer[12] = 0;
971 out->p_buffer[13] = 2*8;
972 /* for each AU length 13 bits + idx 3bits, */
973 SetWBE( out->p_buffer + 14, (in->i_buffer << 3) | 0 );
975 memcpy( &out->p_buffer[16], p_data, i_payload );
977 out->i_buffer = 16 + i_payload;
978 out->i_dts = in->i_dts + i * in->i_length / i_count;
979 out->i_length = in->i_length / i_count;
981 rtp_packetize_send( id, out );
983 p_data += i_payload;
984 i_data -= i_payload;
987 return VLC_SUCCESS;
991 /* rfc2429 */
992 #define RTP_H263_HEADER_SIZE (2) // plen = 0
993 #define RTP_H263_PAYLOAD_START (14) // plen = 0
994 static int rtp_packetize_h263( sout_stream_id_t *id, block_t *in )
996 uint8_t *p_data = in->p_buffer;
997 int i_data = in->i_buffer;
998 int i;
999 int i_max = rtp_mtu (id) - RTP_H263_HEADER_SIZE; /* payload max in one packet */
1000 int i_count;
1001 int b_p_bit;
1002 int b_v_bit = 0; // no pesky error resilience
1003 int i_plen = 0; // normally plen=0 for PSC packet
1004 int i_pebit = 0; // because plen=0
1005 uint16_t h;
1007 if( i_data < 2 )
1009 return VLC_EGENERIC;
1011 if( p_data[0] || p_data[1] )
1013 return VLC_EGENERIC;
1015 /* remove 2 leading 0 bytes */
1016 p_data += 2;
1017 i_data -= 2;
1018 i_count = ( i_data + i_max - 1 ) / i_max;
1020 for( i = 0; i < i_count; i++ )
1022 int i_payload = __MIN( i_max, i_data );
1023 block_t *out = block_Alloc( RTP_H263_PAYLOAD_START + i_payload );
1024 b_p_bit = (i == 0) ? 1 : 0;
1025 h = ( b_p_bit << 10 )|
1026 ( b_v_bit << 9 )|
1027 ( i_plen << 3 )|
1028 i_pebit;
1030 /* rtp common header */
1031 //b_m_bit = 1; // always contains end of frame
1032 rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
1033 in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts );
1035 /* h263 header */
1036 SetWBE( out->p_buffer + 12, h );
1037 memcpy( &out->p_buffer[RTP_H263_PAYLOAD_START], p_data, i_payload );
1039 out->i_buffer = RTP_H263_PAYLOAD_START + i_payload;
1040 out->i_dts = in->i_dts + i * in->i_length / i_count;
1041 out->i_length = in->i_length / i_count;
1043 rtp_packetize_send( id, out );
1045 p_data += i_payload;
1046 i_data -= i_payload;
1049 return VLC_SUCCESS;
1052 /* rfc3984 */
1053 static int
1054 rtp_packetize_h264_nal( sout_stream_id_t *id,
1055 const uint8_t *p_data, int i_data, int64_t i_pts,
1056 int64_t i_dts, bool b_last, int64_t i_length )
1058 const int i_max = rtp_mtu (id); /* payload max in one packet */
1059 int i_nal_hdr;
1060 int i_nal_type;
1062 if( i_data < 5 )
1063 return VLC_SUCCESS;
1065 i_nal_hdr = p_data[3];
1066 i_nal_type = i_nal_hdr&0x1f;
1068 /* Skip start code */
1069 p_data += 3;
1070 i_data -= 3;
1072 /* */
1073 if( i_data <= i_max )
1075 /* Single NAL unit packet */
1076 block_t *out = block_Alloc( 12 + i_data );
1077 out->i_dts = i_dts;
1078 out->i_length = i_length;
1080 /* */
1081 rtp_packetize_common( id, out, b_last, i_pts );
1082 out->i_buffer = 12 + i_data;
1084 memcpy( &out->p_buffer[12], p_data, i_data );
1086 rtp_packetize_send( id, out );
1088 else
1090 /* FU-A Fragmentation Unit without interleaving */
1091 const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2);
1092 int i;
1094 p_data++;
1095 i_data--;
1097 for( i = 0; i < i_count; i++ )
1099 const int i_payload = __MIN( i_data, i_max-2 );
1100 block_t *out = block_Alloc( 12 + 2 + i_payload );
1101 out->i_dts = i_dts + i * i_length / i_count;
1102 out->i_length = i_length / i_count;
1104 /* */
1105 rtp_packetize_common( id, out, (b_last && i_payload == i_data),
1106 i_pts );
1107 out->i_buffer = 14 + i_payload;
1109 /* FU indicator */
1110 out->p_buffer[12] = 0x00 | (i_nal_hdr & 0x60) | 28;
1111 /* FU header */
1112 out->p_buffer[13] = ( i == 0 ? 0x80 : 0x00 ) | ( (i == i_count-1) ? 0x40 : 0x00 ) | i_nal_type;
1113 memcpy( &out->p_buffer[14], p_data, i_payload );
1115 rtp_packetize_send( id, out );
1117 i_data -= i_payload;
1118 p_data += i_payload;
1121 return VLC_SUCCESS;
1124 static int rtp_packetize_h264( sout_stream_id_t *id, block_t *in )
1126 const uint8_t *p_buffer = in->p_buffer;
1127 int i_buffer = in->i_buffer;
1129 while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] != 1 ) )
1131 i_buffer--;
1132 p_buffer++;
1135 /* Split nal units */
1136 while( i_buffer > 4 )
1138 int i_offset;
1139 int i_size = i_buffer;
1140 int i_skip = i_buffer;
1142 /* search nal end */
1143 for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++)
1145 if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 )
1147 /* we found another startcode */
1148 i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 : 0);
1149 i_skip = i_offset;
1150 break;
1153 /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */
1154 rtp_packetize_h264_nal( id, p_buffer, i_size,
1155 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts), in->i_dts,
1156 (i_size >= i_buffer), in->i_length * i_size / in->i_buffer );
1158 i_buffer -= i_skip;
1159 p_buffer += i_skip;
1161 return VLC_SUCCESS;
1164 static int rtp_packetize_amr( sout_stream_id_t *id, block_t *in )
1166 int i_max = rtp_mtu (id) - 2; /* payload max in one packet */
1167 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1169 uint8_t *p_data = in->p_buffer;
1170 int i_data = in->i_buffer;
1171 int i;
1173 /* Only supports octet-aligned mode */
1174 for( i = 0; i < i_count; i++ )
1176 int i_payload = __MIN( i_max, i_data );
1177 block_t *out = block_Alloc( 14 + i_payload );
1179 /* rtp common header */
1180 rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
1181 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
1182 /* Payload header */
1183 out->p_buffer[12] = 0xF0; /* CMR */
1184 out->p_buffer[13] = p_data[0]&0x7C; /* ToC */ /* FIXME: frame type */
1186 /* FIXME: are we fed multiple frames ? */
1187 memcpy( &out->p_buffer[14], p_data+1, i_payload-1 );
1189 out->i_buffer = 14 + i_payload-1;
1190 out->i_dts = in->i_dts + i * in->i_length / i_count;
1191 out->i_length = in->i_length / i_count;
1193 rtp_packetize_send( id, out );
1195 p_data += i_payload;
1196 i_data -= i_payload;
1199 return VLC_SUCCESS;
1202 static int rtp_packetize_t140( sout_stream_id_t *id, block_t *in )
1204 const size_t i_max = rtp_mtu (id);
1205 const uint8_t *p_data = in->p_buffer;
1206 size_t i_data = in->i_buffer;
1208 for( unsigned i_packet = 0; i_data > 0; i_packet++ )
1210 size_t i_payload = i_data;
1212 /* Make sure we stop on an UTF-8 character boundary
1213 * (assuming the input is valid UTF-8) */
1214 if( i_data > i_max )
1216 i_payload = i_max;
1218 while( ( p_data[i_payload] & 0xC0 ) == 0x80 )
1220 if( i_payload == 0 )
1221 return VLC_SUCCESS; /* fishy input! */
1223 i_payload--;
1227 block_t *out = block_Alloc( 12 + i_payload );
1228 if( out == NULL )
1229 return VLC_SUCCESS;
1231 rtp_packetize_common( id, out, 0, in->i_pts + i_packet );
1232 memcpy( out->p_buffer + 12, p_data, i_payload );
1234 out->i_buffer = 12 + i_payload;
1235 out->i_dts = in->i_pts;
1236 out->i_length = 0;
1238 rtp_packetize_send( id, out );
1240 p_data += i_payload;
1241 i_data -= i_payload;
1244 return VLC_SUCCESS;
1248 static int rtp_packetize_spx( sout_stream_id_t *id, block_t *in )
1250 uint8_t *p_buffer = in->p_buffer;
1251 int i_data_size, i_payload_size, i_payload_padding;
1252 i_data_size = i_payload_size = in->i_buffer;
1253 i_payload_padding = 0;
1254 block_t *p_out;
1256 if ( in->i_buffer > rtp_mtu (id) )
1257 return VLC_SUCCESS;
1260 RFC for Speex in RTP says that each packet must end on an octet
1261 boundary. So, we check to see if the number of bytes % 4 is zero.
1262 If not, we have to add some padding.
1264 This MAY be overkill since packetization is handled elsewhere and
1265 appears to ensure the octet boundary. However, better safe than
1266 sorry.
1268 if ( i_payload_size % 4 )
1270 i_payload_padding = 4 - ( i_payload_size % 4 );
1271 i_payload_size += i_payload_padding;
1275 Allocate a new RTP p_output block of the appropriate size.
1276 Allow for 12 extra bytes of RTP header.
1278 p_out = block_Alloc( 12 + i_payload_size );
1280 if ( i_payload_padding )
1283 The padding is required to be a zero followed by all 1s.
1285 char c_first_pad, c_remaining_pad;
1286 c_first_pad = 0x7F;
1287 c_remaining_pad = 0xFF;
1290 Allow for 12 bytes before the i_data_size because
1291 of the expected RTP header added during
1292 rtp_packetize_common.
1294 p_out->p_buffer[12 + i_data_size] = c_first_pad;
1295 switch (i_payload_padding)
1297 case 2:
1298 p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad;
1299 break;
1300 case 3:
1301 p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad;
1302 p_out->p_buffer[12 + i_data_size + 2] = c_remaining_pad;
1303 break;
1307 /* Add the RTP header to our p_output buffer. */
1308 rtp_packetize_common( id, p_out, 0,
1309 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
1310 /* Copy the Speex payload to the p_output buffer */
1311 memcpy( &p_out->p_buffer[12], p_buffer, i_data_size );
1313 p_out->i_buffer = 12 + i_payload_size;
1314 p_out->i_dts = in->i_dts;
1315 p_out->i_length = in->i_length;
1317 /* Queue the buffer for actual transmission. */
1318 rtp_packetize_send( id, p_out );
1319 return VLC_SUCCESS;
1322 static int rtp_packetize_g726( sout_stream_id_t *id, block_t *in, int i_pad )
1324 int i_max = (rtp_mtu( id )- 12 + i_pad - 1) & ~i_pad;
1325 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1327 uint8_t *p_data = in->p_buffer;
1328 int i_data = in->i_buffer;
1329 int i_packet = 0;
1331 while( i_data > 0 )
1333 int i_payload = __MIN( i_max, i_data );
1334 block_t *out = block_New( p_stream, 12 + i_payload );
1336 /* rtp common header */
1337 rtp_packetize_common( id, out, 0,
1338 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
1340 memcpy( &out->p_buffer[12], p_data, i_payload );
1342 out->i_buffer = 12 + i_payload;
1343 out->i_dts = in->i_dts + i_packet++ * in->i_length / i_count;
1344 out->i_length = in->i_length / i_count;
1346 rtp_packetize_send( id, out );
1348 p_data += i_payload;
1349 i_data -= i_payload;
1351 return VLC_SUCCESS;
1354 static int rtp_packetize_g726_16( sout_stream_id_t *id, block_t *in )
1356 return rtp_packetize_g726( id, in, 4 );
1359 static int rtp_packetize_g726_24( sout_stream_id_t *id, block_t *in )
1361 return rtp_packetize_g726( id, in, 8 );
1364 static int rtp_packetize_g726_32( sout_stream_id_t *id, block_t *in )
1366 return rtp_packetize_g726( id, in, 2 );
1369 static int rtp_packetize_g726_40( sout_stream_id_t *id, block_t *in )
1371 return rtp_packetize_g726( id, in, 8 );