Old RC: "rate" is a float nowadays (fix #4088)
[vlc/asuraparaju-public.git] / modules / stream_out / rtpfmt.c
blob482db7d4fc4708eb3416ce7b49e18ddc40d94b9c
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>
33 #include "rtp.h"
35 int
36 rtp_packetize_h264_nal( sout_stream_id_t *id,
37 const uint8_t *p_data, int i_data, int64_t i_pts,
38 int64_t i_dts, bool b_last, int64_t i_length );
40 int rtp_packetize_mpa( sout_stream_id_t *id,
41 block_t *in )
43 int i_max = rtp_mtu (id) - 4; /* payload max in one packet */
44 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
46 uint8_t *p_data = in->p_buffer;
47 int i_data = in->i_buffer;
48 int i;
50 for( i = 0; i < i_count; i++ )
52 int i_payload = __MIN( i_max, i_data );
53 block_t *out = block_Alloc( 16 + i_payload );
55 /* rtp common header */
56 rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
57 /* mbz set to 0 */
58 SetWBE( out->p_buffer + 12, 0 );
59 /* fragment offset in the current frame */
60 SetWBE( out->p_buffer + 14, i * i_max );
61 memcpy( &out->p_buffer[16], p_data, i_payload );
63 out->i_buffer = 16 + i_payload;
64 out->i_dts = in->i_dts + i * in->i_length / i_count;
65 out->i_length = in->i_length / i_count;
67 rtp_packetize_send( id, out );
69 p_data += i_payload;
70 i_data -= i_payload;
73 return VLC_SUCCESS;
76 /* rfc2250 */
77 int rtp_packetize_mpv( sout_stream_id_t *id, block_t *in )
79 int i_max = rtp_mtu (id) - 4; /* payload max in one packet */
80 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
82 uint8_t *p_data = in->p_buffer;
83 int i_data = in->i_buffer;
84 int i;
85 int b_sequence_start = 0;
86 int i_temporal_ref = 0;
87 int i_picture_coding_type = 0;
88 int i_fbv = 0, i_bfc = 0, i_ffv = 0, i_ffc = 0;
89 int b_start_slice = 0;
91 /* preparse this packet to get some info */
92 if( in->i_buffer > 4 )
94 uint8_t *p = p_data;
95 int i_rest = in->i_buffer;
97 for( ;; )
99 while( i_rest > 4 &&
100 ( p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x01 ) )
102 p++;
103 i_rest--;
105 if( i_rest <= 4 )
107 break;
109 p += 3;
110 i_rest -= 4;
112 if( *p == 0xb3 )
114 /* sequence start code */
115 b_sequence_start = 1;
117 else if( *p == 0x00 && i_rest >= 4 )
119 /* picture */
120 i_temporal_ref = ( p[1] << 2) |((p[2]>>6)&0x03);
121 i_picture_coding_type = (p[2] >> 3)&0x07;
123 if( i_rest >= 4 && ( i_picture_coding_type == 2 ||
124 i_picture_coding_type == 3 ) )
126 i_ffv = (p[3] >> 2)&0x01;
127 i_ffc = ((p[3]&0x03) << 1)|((p[4]>>7)&0x01);
128 if( i_rest > 4 && i_picture_coding_type == 3 )
130 i_fbv = (p[4]>>6)&0x01;
131 i_bfc = (p[4]>>3)&0x07;
135 else if( *p <= 0xaf )
137 b_start_slice = 1;
142 for( i = 0; i < i_count; i++ )
144 int i_payload = __MIN( i_max, i_data );
145 block_t *out = block_Alloc( 16 + i_payload );
146 /* 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 */
147 uint32_t h = ( i_temporal_ref << 16 )|
148 ( b_sequence_start << 13 )|
149 ( b_start_slice << 12 )|
150 ( i == i_count - 1 ? 1 << 11 : 0 )|
151 ( i_picture_coding_type << 8 )|
152 ( i_fbv << 7 )|( i_bfc << 4 )|( i_ffv << 3 )|i_ffc;
154 /* rtp common header */
155 rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
156 in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts );
158 SetDWBE( out->p_buffer + 12, h );
160 memcpy( &out->p_buffer[16], p_data, i_payload );
162 out->i_buffer = 16 + i_payload;
163 out->i_dts = in->i_dts + i * in->i_length / i_count;
164 out->i_length = in->i_length / i_count;
166 rtp_packetize_send( id, out );
168 p_data += i_payload;
169 i_data -= i_payload;
172 return VLC_SUCCESS;
175 int rtp_packetize_ac3( sout_stream_id_t *id, block_t *in )
177 int i_max = rtp_mtu (id) - 2; /* payload max in one packet */
178 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
180 uint8_t *p_data = in->p_buffer;
181 int i_data = in->i_buffer;
182 int i;
184 for( i = 0; i < i_count; i++ )
186 int i_payload = __MIN( i_max, i_data );
187 block_t *out = block_Alloc( 14 + i_payload );
189 /* rtp common header */
190 rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
191 /* unit count */
192 out->p_buffer[12] = 1;
193 /* unit header */
194 out->p_buffer[13] = 0x00;
195 /* data */
196 memcpy( &out->p_buffer[14], p_data, i_payload );
198 out->i_buffer = 14 + i_payload;
199 out->i_dts = in->i_dts + i * in->i_length / i_count;
200 out->i_length = in->i_length / i_count;
202 rtp_packetize_send( id, out );
204 p_data += i_payload;
205 i_data -= i_payload;
208 return VLC_SUCCESS;
211 int rtp_packetize_split( sout_stream_id_t *id, block_t *in )
213 int i_max = rtp_mtu (id); /* payload max in one packet */
214 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
216 uint8_t *p_data = in->p_buffer;
217 int i_data = in->i_buffer;
218 int i;
220 for( i = 0; i < i_count; i++ )
222 int i_payload = __MIN( i_max, i_data );
223 block_t *out = block_Alloc( 12 + i_payload );
225 /* rtp common header */
226 rtp_packetize_common( id, out, (i == i_count - 1),
227 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
228 memcpy( &out->p_buffer[12], p_data, i_payload );
230 out->i_buffer = 12 + i_payload;
231 out->i_dts = in->i_dts + i * in->i_length / i_count;
232 out->i_length = in->i_length / i_count;
234 rtp_packetize_send( id, out );
236 p_data += i_payload;
237 i_data -= i_payload;
240 return VLC_SUCCESS;
243 /* split and convert from little endian to network byte order */
244 int rtp_packetize_swab( sout_stream_id_t *id, block_t *in )
246 int i_max = rtp_mtu (id); /* payload max in one packet */
247 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
249 uint8_t *p_data = in->p_buffer;
250 int i_data = in->i_buffer;
251 int i;
253 for( i = 0; i < i_count; i++ )
255 int i_payload = __MIN( i_max, i_data );
256 block_t *out = block_Alloc( 12 + i_payload );
258 /* rtp common header */
259 rtp_packetize_common( id, out, (i == i_count - 1),
260 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
261 swab( p_data, out->p_buffer + 12, i_payload );
263 out->i_buffer = 12 + i_payload;
264 out->i_dts = in->i_dts + i * in->i_length / i_count;
265 out->i_length = in->i_length / i_count;
267 rtp_packetize_send( id, out );
269 p_data += i_payload;
270 i_data -= i_payload;
273 return VLC_SUCCESS;
276 /* rfc3016 */
277 int rtp_packetize_mp4a_latm( sout_stream_id_t *id, block_t *in )
279 int i_max = rtp_mtu (id) - 2; /* payload max in one packet */
280 int latmhdrsize = in->i_buffer / 0xff + 1;
281 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
283 uint8_t *p_data = in->p_buffer, *p_header = NULL;
284 int i_data = in->i_buffer;
285 int i;
287 for( i = 0; i < i_count; i++ )
289 int i_payload = __MIN( i_max, i_data );
290 block_t *out;
292 if( i != 0 )
293 latmhdrsize = 0;
294 out = block_Alloc( 12 + latmhdrsize + i_payload );
296 /* rtp common header */
297 rtp_packetize_common( id, out, ((i == i_count - 1) ? 1 : 0),
298 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
300 if( i == 0 )
302 int tmp = in->i_buffer;
304 p_header=out->p_buffer+12;
305 while( tmp > 0xfe )
307 *p_header = 0xff;
308 p_header++;
309 tmp -= 0xff;
311 *p_header = tmp;
314 memcpy( &out->p_buffer[12+latmhdrsize], p_data, i_payload );
316 out->i_buffer = 12 + latmhdrsize + i_payload;
317 out->i_dts = in->i_dts + i * in->i_length / i_count;
318 out->i_length = in->i_length / i_count;
320 rtp_packetize_send( id, out );
322 p_data += i_payload;
323 i_data -= i_payload;
326 return VLC_SUCCESS;
329 int rtp_packetize_mp4a( sout_stream_id_t *id, block_t *in )
331 int i_max = rtp_mtu (id) - 4; /* payload max in one packet */
332 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
334 uint8_t *p_data = in->p_buffer;
335 int i_data = in->i_buffer;
336 int i;
338 for( i = 0; i < i_count; i++ )
340 int i_payload = __MIN( i_max, i_data );
341 block_t *out = block_Alloc( 16 + i_payload );
343 /* rtp common header */
344 rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
345 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
346 /* AU headers */
347 /* AU headers length (bits) */
348 out->p_buffer[12] = 0;
349 out->p_buffer[13] = 2*8;
350 /* for each AU length 13 bits + idx 3bits, */
351 SetWBE( out->p_buffer + 14, (in->i_buffer << 3) | 0 );
353 memcpy( &out->p_buffer[16], p_data, i_payload );
355 out->i_buffer = 16 + i_payload;
356 out->i_dts = in->i_dts + i * in->i_length / i_count;
357 out->i_length = in->i_length / i_count;
359 rtp_packetize_send( id, out );
361 p_data += i_payload;
362 i_data -= i_payload;
365 return VLC_SUCCESS;
369 /* rfc2429 */
370 #define RTP_H263_HEADER_SIZE (2) // plen = 0
371 #define RTP_H263_PAYLOAD_START (14) // plen = 0
372 int rtp_packetize_h263( sout_stream_id_t *id, block_t *in )
374 uint8_t *p_data = in->p_buffer;
375 int i_data = in->i_buffer;
376 int i;
377 int i_max = rtp_mtu (id) - RTP_H263_HEADER_SIZE; /* payload max in one packet */
378 int i_count;
379 int b_p_bit;
380 int b_v_bit = 0; // no pesky error resilience
381 int i_plen = 0; // normally plen=0 for PSC packet
382 int i_pebit = 0; // because plen=0
383 uint16_t h;
385 if( i_data < 2 )
387 return VLC_EGENERIC;
389 if( p_data[0] || p_data[1] )
391 return VLC_EGENERIC;
393 /* remove 2 leading 0 bytes */
394 p_data += 2;
395 i_data -= 2;
396 i_count = ( i_data + i_max - 1 ) / i_max;
398 for( i = 0; i < i_count; i++ )
400 int i_payload = __MIN( i_max, i_data );
401 block_t *out = block_Alloc( RTP_H263_PAYLOAD_START + i_payload );
402 b_p_bit = (i == 0) ? 1 : 0;
403 h = ( b_p_bit << 10 )|
404 ( b_v_bit << 9 )|
405 ( i_plen << 3 )|
406 i_pebit;
408 /* rtp common header */
409 //b_m_bit = 1; // always contains end of frame
410 rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
411 in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts );
413 /* h263 header */
414 SetWBE( out->p_buffer + 12, h );
415 memcpy( &out->p_buffer[RTP_H263_PAYLOAD_START], p_data, i_payload );
417 out->i_buffer = RTP_H263_PAYLOAD_START + i_payload;
418 out->i_dts = in->i_dts + i * in->i_length / i_count;
419 out->i_length = in->i_length / i_count;
421 rtp_packetize_send( id, out );
423 p_data += i_payload;
424 i_data -= i_payload;
427 return VLC_SUCCESS;
430 /* rfc3984 */
432 rtp_packetize_h264_nal( sout_stream_id_t *id,
433 const uint8_t *p_data, int i_data, int64_t i_pts,
434 int64_t i_dts, bool b_last, int64_t i_length )
436 const int i_max = rtp_mtu (id); /* payload max in one packet */
437 int i_nal_hdr;
438 int i_nal_type;
440 if( i_data < 5 )
441 return VLC_SUCCESS;
443 i_nal_hdr = p_data[3];
444 i_nal_type = i_nal_hdr&0x1f;
446 /* Skip start code */
447 p_data += 3;
448 i_data -= 3;
450 /* */
451 if( i_data <= i_max )
453 /* Single NAL unit packet */
454 block_t *out = block_Alloc( 12 + i_data );
455 out->i_dts = i_dts;
456 out->i_length = i_length;
458 /* */
459 rtp_packetize_common( id, out, b_last, i_pts );
460 out->i_buffer = 12 + i_data;
462 memcpy( &out->p_buffer[12], p_data, i_data );
464 rtp_packetize_send( id, out );
466 else
468 /* FU-A Fragmentation Unit without interleaving */
469 const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2);
470 int i;
472 p_data++;
473 i_data--;
475 for( i = 0; i < i_count; i++ )
477 const int i_payload = __MIN( i_data, i_max-2 );
478 block_t *out = block_Alloc( 12 + 2 + i_payload );
479 out->i_dts = i_dts + i * i_length / i_count;
480 out->i_length = i_length / i_count;
482 /* */
483 rtp_packetize_common( id, out, (b_last && i_payload == i_data),
484 i_pts );
485 out->i_buffer = 14 + i_payload;
487 /* FU indicator */
488 out->p_buffer[12] = 0x00 | (i_nal_hdr & 0x60) | 28;
489 /* FU header */
490 out->p_buffer[13] = ( i == 0 ? 0x80 : 0x00 ) | ( (i == i_count-1) ? 0x40 : 0x00 ) | i_nal_type;
491 memcpy( &out->p_buffer[14], p_data, i_payload );
493 rtp_packetize_send( id, out );
495 i_data -= i_payload;
496 p_data += i_payload;
499 return VLC_SUCCESS;
502 int rtp_packetize_h264( sout_stream_id_t *id, block_t *in )
504 const uint8_t *p_buffer = in->p_buffer;
505 int i_buffer = in->i_buffer;
507 while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] != 1 ) )
509 i_buffer--;
510 p_buffer++;
513 /* Split nal units */
514 while( i_buffer > 4 )
516 int i_offset;
517 int i_size = i_buffer;
518 int i_skip = i_buffer;
520 /* search nal end */
521 for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++)
523 if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 )
525 /* we found another startcode */
526 i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 : 0);
527 i_skip = i_offset;
528 break;
531 /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */
532 rtp_packetize_h264_nal( id, p_buffer, i_size,
533 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts), in->i_dts,
534 (i_size >= i_buffer), in->i_length * i_size / in->i_buffer );
536 i_buffer -= i_skip;
537 p_buffer += i_skip;
539 return VLC_SUCCESS;
542 int rtp_packetize_amr( sout_stream_id_t *id, block_t *in )
544 int i_max = rtp_mtu (id) - 2; /* payload max in one packet */
545 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
547 uint8_t *p_data = in->p_buffer;
548 int i_data = in->i_buffer;
549 int i;
551 /* Only supports octet-aligned mode */
552 for( i = 0; i < i_count; i++ )
554 int i_payload = __MIN( i_max, i_data );
555 block_t *out = block_Alloc( 14 + i_payload );
557 /* rtp common header */
558 rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
559 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
560 /* Payload header */
561 out->p_buffer[12] = 0xF0; /* CMR */
562 out->p_buffer[13] = p_data[0]&0x7C; /* ToC */ /* FIXME: frame type */
564 /* FIXME: are we fed multiple frames ? */
565 memcpy( &out->p_buffer[14], p_data+1, i_payload-1 );
567 out->i_buffer = 14 + i_payload-1;
568 out->i_dts = in->i_dts + i * in->i_length / i_count;
569 out->i_length = in->i_length / i_count;
571 rtp_packetize_send( id, out );
573 p_data += i_payload;
574 i_data -= i_payload;
577 return VLC_SUCCESS;
580 int rtp_packetize_t140( sout_stream_id_t *id, block_t *in )
582 const size_t i_max = rtp_mtu (id);
583 const uint8_t *p_data = in->p_buffer;
584 size_t i_data = in->i_buffer;
586 for( unsigned i_packet = 0; i_data > 0; i_packet++ )
588 size_t i_payload = i_data;
590 /* Make sure we stop on an UTF-8 character boundary
591 * (assuming the input is valid UTF-8) */
592 if( i_data > i_max )
594 i_payload = i_max;
596 while( ( p_data[i_payload] & 0xC0 ) == 0x80 )
598 if( i_payload == 0 )
599 return VLC_SUCCESS; /* fishy input! */
601 i_payload--;
605 block_t *out = block_Alloc( 12 + i_payload );
606 if( out == NULL )
607 return VLC_SUCCESS;
609 rtp_packetize_common( id, out, 0, in->i_pts + i_packet );
610 memcpy( out->p_buffer + 12, p_data, i_payload );
612 out->i_buffer = 12 + i_payload;
613 out->i_dts = out->i_pts;
614 out->i_length = 0;
616 rtp_packetize_send( id, out );
618 p_data += i_payload;
619 i_data -= i_payload;
622 return VLC_SUCCESS;
626 int rtp_packetize_spx( sout_stream_id_t *id, block_t *in )
628 uint8_t *p_buffer = in->p_buffer;
629 int i_data_size, i_payload_size, i_payload_padding;
630 i_data_size = i_payload_size = in->i_buffer;
631 i_payload_padding = 0;
632 block_t *p_out;
634 if ( in->i_buffer > rtp_mtu (id) )
635 return VLC_SUCCESS;
638 RFC for Speex in RTP says that each packet must end on an octet
639 boundary. So, we check to see if the number of bytes % 4 is zero.
640 If not, we have to add some padding.
642 This MAY be overkill since packetization is handled elsewhere and
643 appears to ensure the octet boundary. However, better safe than
644 sorry.
646 if ( i_payload_size % 4 )
648 i_payload_padding = 4 - ( i_payload_size % 4 );
649 i_payload_size += i_payload_padding;
653 Allocate a new RTP p_output block of the appropriate size.
654 Allow for 12 extra bytes of RTP header.
656 p_out = block_Alloc( 12 + i_payload_size );
658 if ( i_payload_padding )
661 The padding is required to be a zero followed by all 1s.
663 char c_first_pad, c_remaining_pad;
664 c_first_pad = 0x7F;
665 c_remaining_pad = 0xFF;
668 Allow for 12 bytes before the i_data_size because
669 of the expected RTP header added during
670 rtp_packetize_common.
672 p_out->p_buffer[12 + i_data_size] = c_first_pad;
673 switch (i_payload_padding)
675 case 2:
676 p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad;
677 break;
678 case 3:
679 p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad;
680 p_out->p_buffer[12 + i_data_size + 2] = c_remaining_pad;
681 break;
685 /* Add the RTP header to our p_output buffer. */
686 rtp_packetize_common( id, p_out, 0,
687 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
688 /* Copy the Speex payload to the p_output buffer */
689 memcpy( &p_out->p_buffer[12], p_buffer, i_data_size );
691 p_out->i_buffer = 12 + i_payload_size;
692 p_out->i_dts = in->i_dts;
693 p_out->i_length = in->i_length;
695 /* Queue the buffer for actual transmission. */
696 rtp_packetize_send( id, p_out );
697 return VLC_SUCCESS;
700 static int rtp_packetize_g726( sout_stream_id_t *id, block_t *in, int i_pad )
702 int i_max = (rtp_mtu( id )- 12 + i_pad - 1) & ~i_pad;
703 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
705 uint8_t *p_data = in->p_buffer;
706 int i_data = in->i_buffer;
707 int i_packet = 0;
709 while( i_data > 0 )
711 int i_payload = __MIN( i_max, i_data );
712 block_t *out = block_New( p_stream, 12 + i_payload );
714 /* rtp common header */
715 rtp_packetize_common( id, out, 0,
716 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
718 memcpy( &out->p_buffer[12], p_data, i_payload );
720 out->i_buffer = 12 + i_payload;
721 out->i_dts = in->i_dts + i_packet++ * in->i_length / i_count;
722 out->i_length = in->i_length / i_count;
724 rtp_packetize_send( id, out );
726 p_data += i_payload;
727 i_data -= i_payload;
729 return VLC_SUCCESS;
732 int rtp_packetize_g726_16( sout_stream_id_t *id, block_t *in )
734 return rtp_packetize_g726( id, in, 4 );
737 int rtp_packetize_g726_24( sout_stream_id_t *id, block_t *in )
739 return rtp_packetize_g726( id, in, 8 );
742 int rtp_packetize_g726_32( sout_stream_id_t *id, block_t *in )
744 return rtp_packetize_g726( id, in, 2 );
747 int rtp_packetize_g726_40( sout_stream_id_t *id, block_t *in )
749 return rtp_packetize_g726( id, in, 8 );