1 /*****************************************************************************
2 * rtpfmt.c: RTP payload formats
3 *****************************************************************************
4 * Copyright (C) 2003-2004 VLC authors and VideoLAN
5 * Copyright © 2007 Rémi Denis-Courmont
8 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
9 * RFC 4175 support based on gstrtpvrawpay.c (LGPL 2) by:
10 * Wim Taymans <wim.taymans@gmail.com>
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU Lesser General Public License as published by
14 * the Free Software Foundation; either version 2.1 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public License
23 * along with this program; if not, write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
31 #include <vlc_common.h>
33 #include <vlc_block.h>
34 #include <vlc_strings.h>
37 #include "../demux/xiph.h"
38 #include "../packetizer/hxxx_nal.h"
42 static int rtp_packetize_mpa (sout_stream_id_sys_t
*, block_t
*);
43 static int rtp_packetize_mpv (sout_stream_id_sys_t
*, block_t
*);
44 static int rtp_packetize_ac3 (sout_stream_id_sys_t
*, block_t
*);
45 static int rtp_packetize_simple(sout_stream_id_sys_t
*, block_t
*);
46 static int rtp_packetize_split(sout_stream_id_sys_t
*, block_t
*);
47 static int rtp_packetize_pcm(sout_stream_id_sys_t
*, block_t
*);
48 static int rtp_packetize_swab (sout_stream_id_sys_t
*, block_t
*);
49 static int rtp_packetize_mp4a (sout_stream_id_sys_t
*, block_t
*);
50 static int rtp_packetize_mp4a_latm (sout_stream_id_sys_t
*, block_t
*);
51 static int rtp_packetize_h263 (sout_stream_id_sys_t
*, block_t
*);
52 static int rtp_packetize_h264 (sout_stream_id_sys_t
*, block_t
*);
53 static int rtp_packetize_h265 (sout_stream_id_sys_t
*, block_t
*);
54 static int rtp_packetize_amr (sout_stream_id_sys_t
*, block_t
*);
55 static int rtp_packetize_spx (sout_stream_id_sys_t
*, block_t
*);
56 static int rtp_packetize_t140 (sout_stream_id_sys_t
*, block_t
*);
57 static int rtp_packetize_g726_16 (sout_stream_id_sys_t
*, block_t
*);
58 static int rtp_packetize_g726_24 (sout_stream_id_sys_t
*, block_t
*);
59 static int rtp_packetize_g726_32 (sout_stream_id_sys_t
*, block_t
*);
60 static int rtp_packetize_g726_40 (sout_stream_id_sys_t
*, block_t
*);
61 static int rtp_packetize_xiph (sout_stream_id_sys_t
*, block_t
*);
62 static int rtp_packetize_vp8 (sout_stream_id_sys_t
*, block_t
*);
63 static int rtp_packetize_jpeg (sout_stream_id_sys_t
*, block_t
*);
64 static int rtp_packetize_r420 (sout_stream_id_sys_t
*, block_t
*);
65 static int rtp_packetize_rgb24 (sout_stream_id_sys_t
*, block_t
*);
67 #define XIPH_IDENT (0)
69 /* Helpers common to xiph codecs (vorbis and theora) */
71 static int rtp_xiph_pack_headers(size_t room
, void *p_extra
, size_t i_extra
,
72 uint8_t **p_buffer
, size_t *i_buffer
,
73 uint8_t *theora_pixel_fmt
)
75 unsigned packet_size
[XIPH_MAX_HEADER_COUNT
];
76 void *packet
[XIPH_MAX_HEADER_COUNT
];
77 unsigned packet_count
;
78 if (xiph_SplitHeaders(packet_size
, packet
, &packet_count
,
84 if (theora_pixel_fmt
!= NULL
)
86 if (packet_size
[0] < 42)
88 *theora_pixel_fmt
= (((uint8_t *)packet
[0])[41] >> 3) & 0x03;
91 unsigned length_size
[2] = { 0, 0 };
92 for (int i
= 0; i
< 2; i
++)
94 unsigned size
= packet_size
[i
];
102 *i_buffer
= room
+ 1 + length_size
[0] + length_size
[1]
103 + packet_size
[0] + packet_size
[1] + packet_size
[2];
104 *p_buffer
= malloc(*i_buffer
);
105 if (*p_buffer
== NULL
)
108 uint8_t *p
= *p_buffer
+ room
;
109 /* Number of headers */
112 for (int i
= 0; i
< 2; i
++)
114 unsigned size
= length_size
[i
];
117 *p
= (packet_size
[i
] >> (7 * (size
- 1))) & 0x7f;
123 for (int i
= 0; i
< 3; i
++)
125 memcpy(p
, packet
[i
], packet_size
[i
]);
132 static char *rtp_xiph_b64_oob_config(void *p_extra
, size_t i_extra
,
133 uint8_t *theora_pixel_fmt
)
137 if (rtp_xiph_pack_headers(9, p_extra
, i_extra
, &p_buffer
, &i_buffer
,
138 theora_pixel_fmt
) != VLC_SUCCESS
)
141 /* Number of packed headers */
142 SetDWBE(p_buffer
, 1);
144 uint32_t ident
= XIPH_IDENT
;
145 SetWBE(p_buffer
+ 4, ident
>> 8);
146 p_buffer
[6] = ident
& 0xff;
148 SetWBE(p_buffer
+ 7, i_buffer
);
150 char *config
= vlc_b64_encode_binary(p_buffer
, i_buffer
);
155 static void sprintf_hexa( char *s
, const uint8_t *p_data
, int i_data
)
157 static const char hex
[16] = "0123456789abcdef";
159 for( int i
= 0; i
< i_data
; i
++ )
161 s
[2*i
+0] = hex
[(p_data
[i
]>>4)&0xf];
162 s
[2*i
+1] = hex
[(p_data
[i
] )&0xf];
167 /* TODO: make this into something more clever than a big switch? */
168 int rtp_get_fmt( vlc_object_t
*obj
, const es_format_t
*p_fmt
, const char *mux
,
169 rtp_format_t
*rtp_fmt
)
171 assert( p_fmt
!= NULL
|| mux
!= NULL
);
173 /* Dynamic payload type. Payload types are scoped to the RTP
174 * session, and we put each ES in its own session, so no risk of
176 rtp_fmt
->payload_type
= 96;
177 rtp_fmt
->cat
= mux
!= NULL
? VIDEO_ES
: p_fmt
->i_cat
;
178 if( rtp_fmt
->cat
== AUDIO_ES
)
180 rtp_fmt
->clock_rate
= p_fmt
->audio
.i_rate
;
181 rtp_fmt
->channels
= p_fmt
->audio
.i_channels
;
184 rtp_fmt
->clock_rate
= 90000; /* most common case for video */
185 /* Stream bitrate in kbps */
186 rtp_fmt
->bitrate
= p_fmt
!= NULL
? p_fmt
->i_bitrate
/1000 : 0;
187 rtp_fmt
->fmtp
= NULL
;
191 if( strncmp( mux
, "ts", 2 ) == 0 )
193 rtp_fmt
->payload_type
= 33;
194 rtp_fmt
->ptname
= "MP2T";
197 rtp_fmt
->ptname
= "MP2P";
201 switch( p_fmt
->i_codec
)
203 case VLC_CODEC_MULAW
:
204 if( p_fmt
->audio
.i_channels
== 1 && p_fmt
->audio
.i_rate
== 8000 )
205 rtp_fmt
->payload_type
= 0;
206 rtp_fmt
->ptname
= "PCMU";
207 rtp_fmt
->pf_packetize
= rtp_packetize_pcm
;
210 if( p_fmt
->audio
.i_channels
== 1 && p_fmt
->audio
.i_rate
== 8000 )
211 rtp_fmt
->payload_type
= 8;
212 rtp_fmt
->ptname
= "PCMA";
213 rtp_fmt
->pf_packetize
= rtp_packetize_pcm
;
217 if( p_fmt
->audio
.i_channels
== 1 && p_fmt
->audio
.i_rate
== 44100 )
219 rtp_fmt
->payload_type
= 11;
221 else if( p_fmt
->audio
.i_channels
== 2 &&
222 p_fmt
->audio
.i_rate
== 44100 )
224 rtp_fmt
->payload_type
= 10;
226 rtp_fmt
->ptname
= "L16";
227 if( p_fmt
->i_codec
== VLC_CODEC_S16B
)
228 rtp_fmt
->pf_packetize
= rtp_packetize_pcm
;
230 rtp_fmt
->pf_packetize
= rtp_packetize_swab
;
233 rtp_fmt
->ptname
= "L8";
234 rtp_fmt
->pf_packetize
= rtp_packetize_pcm
;
237 rtp_fmt
->ptname
= "L24";
238 rtp_fmt
->pf_packetize
= rtp_packetize_pcm
;
241 rtp_fmt
->payload_type
= 14;
242 rtp_fmt
->ptname
= "MPA";
243 rtp_fmt
->clock_rate
= 90000; /* not 44100 */
244 rtp_fmt
->pf_packetize
= rtp_packetize_mpa
;
247 rtp_fmt
->payload_type
= 32;
248 rtp_fmt
->ptname
= "MPV";
249 rtp_fmt
->pf_packetize
= rtp_packetize_mpv
;
251 case VLC_CODEC_ADPCM_G726
:
252 switch( p_fmt
->i_bitrate
/ 1000 )
255 rtp_fmt
->ptname
= "G726-16";
256 rtp_fmt
->pf_packetize
= rtp_packetize_g726_16
;
259 rtp_fmt
->ptname
= "G726-24";
260 rtp_fmt
->pf_packetize
= rtp_packetize_g726_24
;
263 rtp_fmt
->ptname
= "G726-32";
264 rtp_fmt
->pf_packetize
= rtp_packetize_g726_32
;
267 rtp_fmt
->ptname
= "G726-40";
268 rtp_fmt
->pf_packetize
= rtp_packetize_g726_40
;
271 msg_Err( obj
, "cannot add this stream (unsupported "
272 "G.726 bit rate: %u)", p_fmt
->i_bitrate
);
277 rtp_fmt
->ptname
= "ac3";
278 rtp_fmt
->pf_packetize
= rtp_packetize_ac3
;
281 rtp_fmt
->ptname
= "H263-1998";
282 rtp_fmt
->pf_packetize
= rtp_packetize_h263
;
285 rtp_fmt
->ptname
= "H264";
286 rtp_fmt
->pf_packetize
= rtp_packetize_h264
;
287 rtp_fmt
->fmtp
= NULL
;
289 if( p_fmt
->i_extra
> 0 )
291 char *p_64_sps
= NULL
;
292 char *p_64_pps
= NULL
;
295 hxxx_iterator_ctx_t it
;
296 hxxx_iterator_init( &it
, p_fmt
->p_extra
, p_fmt
->i_extra
, 0 );
298 const uint8_t *p_nal
;
300 while( hxxx_annexb_iterate_next( &it
, &p_nal
, &i_nal
) )
304 msg_Dbg( obj
, "No-info found in nal ");
308 const int i_nal_type
= p_nal
[0]&0x1f;
310 msg_Dbg( obj
, "we found a startcode for NAL with TYPE:%d", i_nal_type
);
312 if( i_nal_type
== 7 && i_nal
>= 4 )
315 p_64_sps
= vlc_b64_encode_binary( p_nal
, i_nal
);
316 sprintf_hexa( hexa
, &p_nal
[1], 3 );
318 else if( i_nal_type
== 8 )
321 p_64_pps
= vlc_b64_encode_binary( p_nal
, i_nal
);
326 if( p_64_sps
&& p_64_pps
&&
327 ( asprintf( &rtp_fmt
->fmtp
,
328 "packetization-mode=1;profile-level-id=%s;"
329 "sprop-parameter-sets=%s,%s;", hexa
, p_64_sps
,
331 rtp_fmt
->fmtp
= NULL
;
335 if( rtp_fmt
->fmtp
== NULL
)
336 rtp_fmt
->fmtp
= strdup( "packetization-mode=1" );
341 rtp_fmt
->ptname
= "H265";
342 rtp_fmt
->pf_packetize
= rtp_packetize_h265
;
343 rtp_fmt
->fmtp
= NULL
;
345 int i_profile
= p_fmt
->i_profile
;
346 int i_level
= p_fmt
->i_level
;
353 const uint8_t i_extend
;
354 const char *psz_name
;
357 { 32, 0, "vps", NULL
},
358 { 33, 0, "sps", NULL
},
359 { 34, 0, "pps", NULL
},
360 { 39, 1, "sei", NULL
},
363 if( p_fmt
->i_extra
> 0 )
365 hxxx_iterator_ctx_t it
;
366 for(int i
=0; i
<4; i
++)
368 struct nalset_e
*set
= &nalsets
[i
];
370 hxxx_iterator_init( &it
, p_fmt
->p_extra
, p_fmt
->i_extra
, 0 );
371 const uint8_t *p_nal
;
373 while( hxxx_annexb_iterate_next( &it
, &p_nal
, &i_nal
) )
375 const uint8_t i_nal_type
= (p_nal
[0] & 0x7E) >> 1;
376 if( i_nal_type
< set
->i_nal
||
377 i_nal_type
> set
->i_nal
+ set
->i_extend
)
379 msg_Dbg( obj
, "we found a startcode for NAL with TYPE:%" PRIu8
, i_nal_type
);
381 char *psz_temp
= vlc_b64_encode_binary( p_nal
, i_nal
);
384 if( set
->psz_64
== NULL
)
386 set
->psz_64
= psz_temp
;
391 if( asprintf( &psz_merged
, "%s,%s", set
->psz_64
, psz_temp
) != -1 )
394 set
->psz_64
= psz_merged
;
400 if( i_nal_type
== 33 && i_nal
> 12 )
403 i_profile
= p_nal
[1] & 0x1F;
405 i_space
= p_nal
[1] >> 6;
407 i_tiers
= !!(p_nal
[1] & 0x20);
415 rtp_fmt
->fmtp
= strdup( "tx-mode=SRST;" );
419 if( i_profile
>= 0 &&
420 asprintf( &psz_fmtp
, "%sprofile-id=%d;",
421 rtp_fmt
->fmtp
, i_profile
) != -1 )
423 free( rtp_fmt
->fmtp
);
424 rtp_fmt
->fmtp
= psz_fmtp
;
427 asprintf( &psz_fmtp
, "%slevel-id=%d;",
428 rtp_fmt
->fmtp
, i_level
) != -1 )
430 free( rtp_fmt
->fmtp
);
431 rtp_fmt
->fmtp
= psz_fmtp
;
434 asprintf( &psz_fmtp
, "%stier-flag=%d;",
435 rtp_fmt
->fmtp
, i_tiers
) != -1 )
437 free( rtp_fmt
->fmtp
);
438 rtp_fmt
->fmtp
= psz_fmtp
;
441 asprintf( &psz_fmtp
, "%sprofile-space=%d;",
442 rtp_fmt
->fmtp
, i_space
) != -1 )
444 free( rtp_fmt
->fmtp
);
445 rtp_fmt
->fmtp
= psz_fmtp
;
448 for(int i
=0; i
<4; i
++)
450 struct nalset_e
*set
= &nalsets
[i
];
452 asprintf( &psz_fmtp
, "%ssprop-%s=%s;",
455 set
->psz_64
) != -1 )
457 free( rtp_fmt
->fmtp
);
458 rtp_fmt
->fmtp
= psz_fmtp
;
463 for(int i
=0; i
<4; i
++)
464 free( nalsets
[i
].psz_64
);
471 rtp_fmt
->ptname
= "MP4V-ES";
472 rtp_fmt
->pf_packetize
= rtp_packetize_split
;
473 if( p_fmt
->i_extra
> 0 )
475 char hexa
[2*p_fmt
->i_extra
+1];
476 sprintf_hexa( hexa
, p_fmt
->p_extra
, p_fmt
->i_extra
);
477 if( asprintf( &rtp_fmt
->fmtp
,
478 "profile-level-id=3; config=%s;", hexa
) == -1 )
479 rtp_fmt
->fmtp
= NULL
;
485 if( ! var_InheritBool( obj
, "sout-rtp-mp4a-latm" ) )
487 char hexa
[2*p_fmt
->i_extra
+1];
489 rtp_fmt
->ptname
= "mpeg4-generic";
490 rtp_fmt
->pf_packetize
= rtp_packetize_mp4a
;
491 sprintf_hexa( hexa
, p_fmt
->p_extra
, p_fmt
->i_extra
);
492 if( asprintf( &rtp_fmt
->fmtp
,
493 "streamtype=5; profile-level-id=15; "
494 "mode=AAC-hbr; config=%s; SizeLength=13; "
495 "IndexLength=3; IndexDeltaLength=3; Profile=1;",
497 rtp_fmt
->fmtp
= NULL
;
503 unsigned char config
[6];
504 unsigned int aacsrates
[15] = {
505 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
506 16000, 12000, 11025, 8000, 7350, 0, 0 };
508 for( i
= 0; i
< 15; i
++ )
509 if( p_fmt
->audio
.i_rate
== aacsrates
[i
] )
515 config
[3]=p_fmt
->audio
.i_channels
<<4;
519 rtp_fmt
->ptname
= "MP4A-LATM";
520 rtp_fmt
->pf_packetize
= rtp_packetize_mp4a_latm
;
521 sprintf_hexa( hexa
, config
, 6 );
522 if( asprintf( &rtp_fmt
->fmtp
, "profile-level-id=15; "
523 "object=2; cpresent=0; config=%s", hexa
) == -1 )
524 rtp_fmt
->fmtp
= NULL
;
528 case VLC_CODEC_AMR_NB
:
529 rtp_fmt
->ptname
= "AMR";
530 rtp_fmt
->fmtp
= strdup( "octet-align=1" );
531 rtp_fmt
->pf_packetize
= rtp_packetize_amr
;
533 case VLC_CODEC_AMR_WB
:
534 rtp_fmt
->ptname
= "AMR-WB";
535 rtp_fmt
->fmtp
= strdup( "octet-align=1" );
536 rtp_fmt
->pf_packetize
= rtp_packetize_amr
;
538 case VLC_CODEC_SPEEX
:
539 rtp_fmt
->ptname
= "SPEEX";
540 rtp_fmt
->pf_packetize
= rtp_packetize_spx
;
542 case VLC_CODEC_VORBIS
:
543 rtp_fmt
->ptname
= "vorbis";
544 rtp_fmt
->pf_packetize
= rtp_packetize_xiph
;
545 if( p_fmt
->i_extra
> 0 )
547 rtp_fmt
->fmtp
= NULL
;
548 char *config
= rtp_xiph_b64_oob_config(p_fmt
->p_extra
,
549 p_fmt
->i_extra
, NULL
);
552 if( asprintf( &rtp_fmt
->fmtp
,
553 "configuration=%s;", config
) == -1 )
554 rtp_fmt
->fmtp
= NULL
;
558 case VLC_CODEC_THEORA
:
559 rtp_fmt
->ptname
= "theora";
560 rtp_fmt
->pf_packetize
= rtp_packetize_xiph
;
561 if( p_fmt
->i_extra
> 0 )
563 rtp_fmt
->fmtp
= NULL
;
564 uint8_t pixel_fmt
, c1
, c2
;
565 char *config
= rtp_xiph_b64_oob_config(p_fmt
->p_extra
,
590 vlc_assert_unreachable();
593 if( asprintf( &rtp_fmt
->fmtp
,
594 "sampling=YCbCr-4:%d:%d; width=%d; height=%d; "
595 "delivery-method=inline; configuration=%s; "
596 "delivery-method=in_band;", c1
, c2
,
597 p_fmt
->video
.i_width
, p_fmt
->video
.i_height
,
599 rtp_fmt
->fmtp
= NULL
;
603 case VLC_CODEC_ITU_T140
:
604 rtp_fmt
->ptname
= "t140" ;
605 rtp_fmt
->clock_rate
= 1000;
606 rtp_fmt
->pf_packetize
= rtp_packetize_t140
;
609 rtp_fmt
->payload_type
= 3;
610 rtp_fmt
->ptname
= "GSM";
611 rtp_fmt
->pf_packetize
= rtp_packetize_split
;
614 if (p_fmt
->audio
.i_channels
> 2)
616 msg_Err( obj
, "Multistream opus not supported in RTP"
617 " (having %d channels input)",
618 p_fmt
->audio
.i_channels
);
621 rtp_fmt
->ptname
= "opus";
622 rtp_fmt
->pf_packetize
= rtp_packetize_simple
;
623 rtp_fmt
->clock_rate
= 48000;
624 rtp_fmt
->channels
= 2;
625 if (p_fmt
->audio
.i_channels
== 2)
626 rtp_fmt
->fmtp
= strdup( "sprop-stereo=1" );
629 rtp_fmt
->ptname
= "VP8";
630 rtp_fmt
->pf_packetize
= rtp_packetize_vp8
;
633 rtp_fmt
->ptname
= "RAW";
634 rtp_fmt
->pf_packetize
= rtp_packetize_r420
;
635 if( asprintf( &rtp_fmt
->fmtp
,
636 "sampling=YCbCr-4:2:0; width=%d; height=%d; "
637 "depth=8; colorimetry=BT%s",
638 p_fmt
->video
.i_visible_width
, p_fmt
->video
.i_visible_height
,
639 p_fmt
->video
.i_visible_height
> 576 ? "709-2" : "601-5") == -1 )
641 rtp_fmt
->fmtp
= NULL
;
645 case VLC_CODEC_RGB24
:
646 rtp_fmt
->ptname
= "RAW";
647 rtp_fmt
->pf_packetize
= rtp_packetize_rgb24
;
648 if( asprintf( &rtp_fmt
->fmtp
,
649 "sampling=RGB; width=%d; height=%d; "
650 "depth=8; colorimetry=SMPTE240M",
651 p_fmt
->video
.i_visible_width
,
652 p_fmt
->video
.i_visible_height
) == -1 )
654 rtp_fmt
->fmtp
= NULL
;
660 rtp_fmt
->ptname
= "JPEG";
661 rtp_fmt
->payload_type
= 26;
662 rtp_fmt
->pf_packetize
= rtp_packetize_jpeg
;
666 msg_Err( obj
, "cannot add this stream (unsupported "
667 "codec: %4.4s)", (char*)&p_fmt
->i_codec
);
676 rtp_packetize_h264_nal( sout_stream_id_sys_t
*id
,
677 const uint8_t *p_data
, int i_data
, int64_t i_pts
,
678 int64_t i_dts
, bool b_last
, int64_t i_length
);
680 int rtp_packetize_xiph_config( sout_stream_id_sys_t
*id
, const char *fmtp
,
686 /* extract base64 configuration from fmtp */
687 char *start
= strstr(fmtp
, "configuration=");
688 assert(start
!= NULL
);
689 start
+= sizeof("configuration=") - 1;
690 char *end
= strchr(start
, ';');
692 size_t len
= end
- start
;
694 char *b64
= malloc(len
+ 1);
698 memcpy(b64
, start
, len
);
701 int i_max
= rtp_mtu (id
) - 6; /* payload max in one packet */
703 uint8_t *p_orig
, *p_data
;
706 i_data
= vlc_b64_decode_binary(&p_orig
, b64
);
716 int i_count
= ( i_data
+ i_max
- 1 ) / i_max
;
718 for( int i
= 0; i
< i_count
; i
++ )
720 int i_payload
= __MIN( i_max
, i_data
);
721 block_t
*out
= block_Alloc( 18 + i_payload
);
723 unsigned fragtype
, numpkts
;
734 else if (i
== i_count
- 1)
739 /* Ident:24, Fragment type:2, Vorbis/Theora Data Type:2, # of pkts:4 */
740 uint32_t header
= ((XIPH_IDENT
& 0xffffff) << 8) |
741 (fragtype
<< 6) | (1 << 4) | numpkts
;
743 /* rtp common header */
744 rtp_packetize_common( id
, out
, 0, i_pts
);
746 SetDWBE( out
->p_buffer
+ 12, header
);
747 SetWBE( out
->p_buffer
+ 16, i_payload
);
748 memcpy( &out
->p_buffer
[18], p_data
, i_payload
);
752 rtp_packetize_send( id
, out
);
764 static int rtp_packetize_xiph( sout_stream_id_sys_t
*id
, block_t
*in
)
766 int i_max
= rtp_mtu (id
) - 6; /* payload max in one packet */
767 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
769 uint8_t *p_data
= in
->p_buffer
;
770 int i_data
= in
->i_buffer
;
772 for( int i
= 0; i
< i_count
; i
++ )
774 int i_payload
= __MIN( i_max
, i_data
);
775 block_t
*out
= block_Alloc( 18 + i_payload
);
777 unsigned fragtype
, numpkts
;
780 /* No fragmentation */
790 else if (i
== i_count
- 1)
795 /* Ident:24, Fragment type:2, Vorbis/Theora Data Type:2, # of pkts:4 */
796 uint32_t header
= ((XIPH_IDENT
& 0xffffff) << 8) |
797 (fragtype
<< 6) | (0 << 4) | numpkts
;
799 /* rtp common header */
800 rtp_packetize_common( id
, out
, 0, in
->i_pts
);
802 SetDWBE( out
->p_buffer
+ 12, header
);
803 SetWBE( out
->p_buffer
+ 16, i_payload
);
804 memcpy( &out
->p_buffer
[18], p_data
, i_payload
);
806 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
807 out
->i_length
= in
->i_length
/ i_count
;
809 rtp_packetize_send( id
, out
);
819 static int rtp_packetize_mpa( sout_stream_id_sys_t
*id
, block_t
*in
)
821 int i_max
= rtp_mtu (id
) - 4; /* payload max in one packet */
822 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
824 uint8_t *p_data
= in
->p_buffer
;
825 int i_data
= in
->i_buffer
;
828 for( i
= 0; i
< i_count
; i
++ )
830 int i_payload
= __MIN( i_max
, i_data
);
831 block_t
*out
= block_Alloc( 16 + i_payload
);
833 /* rtp common header */
834 rtp_packetize_common( id
, out
, (i
== i_count
- 1)?1:0, in
->i_pts
);
836 SetWBE( out
->p_buffer
+ 12, 0 );
837 /* fragment offset in the current frame */
838 SetWBE( out
->p_buffer
+ 14, i
* i_max
);
839 memcpy( &out
->p_buffer
[16], p_data
, i_payload
);
841 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
842 out
->i_length
= in
->i_length
/ i_count
;
844 rtp_packetize_send( id
, out
);
855 static int rtp_packetize_mpv( sout_stream_id_sys_t
*id
, block_t
*in
)
857 int i_max
= rtp_mtu (id
) - 4; /* payload max in one packet */
858 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
860 uint8_t *p_data
= in
->p_buffer
;
861 int i_data
= in
->i_buffer
;
863 int b_sequence_start
= 0;
864 int i_temporal_ref
= 0;
865 int i_picture_coding_type
= 0;
866 int i_fbv
= 0, i_bfc
= 0, i_ffv
= 0, i_ffc
= 0;
867 int b_start_slice
= 0;
869 /* preparse this packet to get some info */
870 hxxx_iterator_ctx_t it
;
871 hxxx_iterator_init( &it
, in
->p_buffer
, in
->i_buffer
, 0 );
872 const uint8_t *p_seq
;
874 while( hxxx_annexb_iterate_next( &it
, &p_seq
, &i_seq
) )
876 const uint8_t *p
= p_seq
;
879 /* sequence start code */
880 b_sequence_start
= 1;
882 else if( *p
== 0x00 && i_seq
>= 5 )
885 i_temporal_ref
= ( p
[1] << 2) |((p
[2]>>6)&0x03);
886 i_picture_coding_type
= (p
[2] >> 3)&0x07;
888 if( i_picture_coding_type
== 2 ||
889 i_picture_coding_type
== 3 )
891 i_ffv
= (p
[3] >> 2)&0x01;
892 i_ffc
= ((p
[3]&0x03) << 1)|((p
[4]>>7)&0x01);
893 if( i_seq
> 5 && i_picture_coding_type
== 3 )
895 i_fbv
= (p
[4]>>6)&0x01;
896 i_bfc
= (p
[4]>>3)&0x07;
900 else if( *p
<= 0xaf )
906 for( i
= 0; i
< i_count
; i
++ )
908 int i_payload
= __MIN( i_max
, i_data
);
909 block_t
*out
= block_Alloc( 16 + i_payload
);
910 /* 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 */
911 uint32_t h
= ( i_temporal_ref
<< 16 )|
912 ( b_sequence_start
<< 13 )|
913 ( b_start_slice
<< 12 )|
914 ( i
== i_count
- 1 ? 1 << 11 : 0 )|
915 ( i_picture_coding_type
<< 8 )|
916 ( i_fbv
<< 7 )|( i_bfc
<< 4 )|( i_ffv
<< 3 )|i_ffc
;
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 SetDWBE( out
->p_buffer
+ 12, h
);
924 memcpy( &out
->p_buffer
[16], p_data
, i_payload
);
926 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
927 out
->i_length
= in
->i_length
/ i_count
;
929 rtp_packetize_send( id
, out
);
939 static int rtp_packetize_ac3( sout_stream_id_sys_t
*id
, block_t
*in
)
941 int i_max
= rtp_mtu (id
) - 2; /* payload max in one packet */
942 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
944 uint8_t *p_data
= in
->p_buffer
;
945 int i_data
= in
->i_buffer
;
948 for( i
= 0; i
< i_count
; i
++ )
950 int i_payload
= __MIN( i_max
, i_data
);
951 block_t
*out
= block_Alloc( 14 + i_payload
);
953 /* rtp common header */
954 rtp_packetize_common( id
, out
, (i
== i_count
- 1)?1:0, in
->i_pts
);
956 out
->p_buffer
[12] = 1;
958 out
->p_buffer
[13] = 0x00;
960 memcpy( &out
->p_buffer
[14], p_data
, i_payload
);
962 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
963 out
->i_length
= in
->i_length
/ i_count
;
965 rtp_packetize_send( id
, out
);
975 static int rtp_packetize_simple(sout_stream_id_sys_t
*id
, block_t
*block
)
977 bool marker
= (block
->i_flags
& BLOCK_FLAG_DISCONTINUITY
) != 0;
979 block
= block_Realloc(block
, 12, block
->i_buffer
);
980 if (unlikely(block
== NULL
))
983 rtp_packetize_common(id
, block
, marker
, block
->i_pts
);
984 rtp_packetize_send(id
, block
);
988 static int rtp_packetize_split( sout_stream_id_sys_t
*id
, block_t
*in
)
990 int i_max
= rtp_mtu (id
); /* payload max in one packet */
991 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
993 uint8_t *p_data
= in
->p_buffer
;
994 int i_data
= in
->i_buffer
;
997 for( i
= 0; i
< i_count
; i
++ )
999 int i_payload
= __MIN( i_max
, i_data
);
1000 block_t
*out
= block_Alloc( 12 + i_payload
);
1002 /* rtp common header */
1003 rtp_packetize_common( id
, out
, (i
== i_count
- 1),
1004 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1005 memcpy( &out
->p_buffer
[12], p_data
, i_payload
);
1007 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
1008 out
->i_length
= in
->i_length
/ i_count
;
1010 rtp_packetize_send( id
, out
);
1012 p_data
+= i_payload
;
1013 i_data
-= i_payload
;
1020 static int rtp_packetize_pcm(sout_stream_id_sys_t
*id
, block_t
*in
)
1022 unsigned max
= rtp_mtu(id
);
1024 while (in
->i_buffer
> max
)
1026 unsigned duration
= (in
->i_length
* max
) / in
->i_buffer
;
1027 bool marker
= (in
->i_flags
& BLOCK_FLAG_DISCONTINUITY
) != 0;
1029 block_t
*out
= block_Alloc(12 + max
);
1030 if (unlikely(out
== NULL
))
1036 rtp_packetize_common(id
, out
, marker
, in
->i_pts
);
1037 memcpy(out
->p_buffer
+ 12, in
->p_buffer
, max
);
1038 rtp_packetize_send(id
, out
);
1040 in
->p_buffer
+= max
;
1041 in
->i_buffer
-= max
;
1042 in
->i_pts
+= duration
;
1043 in
->i_length
-= duration
;
1044 in
->i_flags
&= ~BLOCK_FLAG_DISCONTINUITY
;
1047 return rtp_packetize_simple(id
, in
); /* zero copy for the last frame */
1050 /* split and convert from little endian to network byte order */
1051 static int rtp_packetize_swab(sout_stream_id_sys_t
*id
, block_t
*in
)
1053 unsigned max
= rtp_mtu(id
);
1055 while (in
->i_buffer
> 0)
1057 unsigned payload
= (max
< in
->i_buffer
) ? max
: in
->i_buffer
;
1058 unsigned duration
= (in
->i_length
* payload
) / in
->i_buffer
;
1059 bool marker
= (in
->i_flags
& BLOCK_FLAG_DISCONTINUITY
) != 0;
1061 block_t
*out
= block_Alloc(12 + payload
);
1062 if (unlikely(out
== NULL
))
1068 rtp_packetize_common(id
, out
, marker
, in
->i_pts
);
1069 swab(in
->p_buffer
, out
->p_buffer
+ 12, payload
);
1070 rtp_packetize_send(id
, out
);
1072 in
->p_buffer
+= payload
;
1073 in
->i_buffer
-= payload
;
1074 in
->i_pts
+= duration
;
1075 in
->i_length
-= duration
;
1076 in
->i_flags
&= ~BLOCK_FLAG_DISCONTINUITY
;
1084 static int rtp_packetize_mp4a_latm( sout_stream_id_sys_t
*id
, block_t
*in
)
1086 int i_max
= rtp_mtu (id
) - 2; /* payload max in one packet */
1087 int latmhdrsize
= in
->i_buffer
/ 0xff + 1;
1088 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
1090 uint8_t *p_data
= in
->p_buffer
, *p_header
= NULL
;
1091 int i_data
= in
->i_buffer
;
1094 for( i
= 0; i
< i_count
; i
++ )
1096 int i_payload
= __MIN( i_max
, i_data
);
1101 out
= block_Alloc( 12 + latmhdrsize
+ i_payload
);
1103 /* rtp common header */
1104 rtp_packetize_common( id
, out
, ((i
== i_count
- 1) ? 1 : 0),
1105 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1109 int tmp
= in
->i_buffer
;
1111 p_header
=out
->p_buffer
+12;
1121 memcpy( &out
->p_buffer
[12+latmhdrsize
], p_data
, i_payload
);
1123 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
1124 out
->i_length
= in
->i_length
/ i_count
;
1126 rtp_packetize_send( id
, out
);
1128 p_data
+= i_payload
;
1129 i_data
-= i_payload
;
1136 static int rtp_packetize_mp4a( sout_stream_id_sys_t
*id
, block_t
*in
)
1138 int i_max
= rtp_mtu (id
) - 4; /* payload max in one packet */
1139 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
1141 uint8_t *p_data
= in
->p_buffer
;
1142 int i_data
= in
->i_buffer
;
1145 for( i
= 0; i
< i_count
; i
++ )
1147 int i_payload
= __MIN( i_max
, i_data
);
1148 block_t
*out
= block_Alloc( 16 + i_payload
);
1150 /* rtp common header */
1151 rtp_packetize_common( id
, out
, ((i
== i_count
- 1)?1:0),
1152 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1154 /* AU headers length (bits) */
1155 out
->p_buffer
[12] = 0;
1156 out
->p_buffer
[13] = 2*8;
1157 /* for each AU length 13 bits + idx 3bits, */
1158 SetWBE( out
->p_buffer
+ 14, (in
->i_buffer
<< 3) | 0 );
1160 memcpy( &out
->p_buffer
[16], p_data
, i_payload
);
1162 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
1163 out
->i_length
= in
->i_length
/ i_count
;
1165 rtp_packetize_send( id
, out
);
1167 p_data
+= i_payload
;
1168 i_data
-= i_payload
;
1177 #define RTP_H263_HEADER_SIZE (2) // plen = 0
1178 #define RTP_H263_PAYLOAD_START (14) // plen = 0
1179 static int rtp_packetize_h263( sout_stream_id_sys_t
*id
, block_t
*in
)
1181 uint8_t *p_data
= in
->p_buffer
;
1182 int i_data
= in
->i_buffer
;
1184 int i_max
= rtp_mtu (id
) - RTP_H263_HEADER_SIZE
; /* payload max in one packet */
1187 int b_v_bit
= 0; // no pesky error resilience
1188 int i_plen
= 0; // normally plen=0 for PSC packet
1189 int i_pebit
= 0; // because plen=0
1195 return VLC_EGENERIC
;
1197 if( p_data
[0] || p_data
[1] )
1200 return VLC_EGENERIC
;
1202 /* remove 2 leading 0 bytes */
1205 i_count
= ( i_data
+ i_max
- 1 ) / i_max
;
1207 for( i
= 0; i
< i_count
; i
++ )
1209 int i_payload
= __MIN( i_max
, i_data
);
1210 block_t
*out
= block_Alloc( RTP_H263_PAYLOAD_START
+ i_payload
);
1211 b_p_bit
= (i
== 0) ? 1 : 0;
1212 h
= ( b_p_bit
<< 10 )|
1217 /* rtp common header */
1218 //b_m_bit = 1; // always contains end of frame
1219 rtp_packetize_common( id
, out
, (i
== i_count
- 1)?1:0,
1220 in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
);
1223 SetWBE( out
->p_buffer
+ 12, h
);
1224 memcpy( &out
->p_buffer
[RTP_H263_PAYLOAD_START
], p_data
, i_payload
);
1226 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
1227 out
->i_length
= in
->i_length
/ i_count
;
1229 rtp_packetize_send( id
, out
);
1231 p_data
+= i_payload
;
1232 i_data
-= i_payload
;
1241 rtp_packetize_h264_nal( sout_stream_id_sys_t
*id
,
1242 const uint8_t *p_data
, int i_data
, int64_t i_pts
,
1243 int64_t i_dts
, bool b_last
, int64_t i_length
)
1245 const int i_max
= rtp_mtu (id
); /* payload max in one packet */
1252 i_nal_hdr
= p_data
[0];
1253 i_nal_type
= i_nal_hdr
&0x1f;
1256 if( i_data
<= i_max
)
1258 /* Single NAL unit packet */
1259 block_t
*out
= block_Alloc( 12 + i_data
);
1261 out
->i_length
= i_length
;
1264 rtp_packetize_common( id
, out
, b_last
, i_pts
);
1266 memcpy( &out
->p_buffer
[12], p_data
, i_data
);
1268 rtp_packetize_send( id
, out
);
1272 /* FU-A Fragmentation Unit without interleaving */
1273 const int i_count
= ( i_data
-1 + i_max
-2 - 1 ) / (i_max
-2);
1279 for( i
= 0; i
< i_count
; i
++ )
1281 const int i_payload
= __MIN( i_data
, i_max
-2 );
1282 block_t
*out
= block_Alloc( 12 + 2 + i_payload
);
1283 out
->i_dts
= i_dts
+ i
* i_length
/ i_count
;
1284 out
->i_length
= i_length
/ i_count
;
1287 rtp_packetize_common( id
, out
, (b_last
&& i_payload
== i_data
),
1290 out
->p_buffer
[12] = 0x00 | (i_nal_hdr
& 0x60) | 28;
1292 out
->p_buffer
[13] = ( i
== 0 ? 0x80 : 0x00 ) | ( (i
== i_count
-1) ? 0x40 : 0x00 ) | i_nal_type
;
1293 memcpy( &out
->p_buffer
[14], p_data
, i_payload
);
1295 rtp_packetize_send( id
, out
);
1297 i_data
-= i_payload
;
1298 p_data
+= i_payload
;
1304 static int rtp_packetize_h264( sout_stream_id_sys_t
*id
, block_t
*in
)
1306 hxxx_iterator_ctx_t it
;
1307 hxxx_iterator_init( &it
, in
->p_buffer
, in
->i_buffer
, 0 );
1309 const uint8_t *p_nal
;
1311 while( hxxx_annexb_iterate_next( &it
, &p_nal
, &i_nal
) )
1313 /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */
1314 rtp_packetize_h264_nal( id
, p_nal
, i_nal
,
1315 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
), in
->i_dts
,
1316 it
.p_head
+ 3 >= it
.p_tail
, in
->i_length
* i_nal
/ in
->i_buffer
);
1325 rtp_packetize_h265_nal( sout_stream_id_sys_t
*id
,
1326 const uint8_t *p_data
, size_t i_data
, int64_t i_pts
,
1327 int64_t i_dts
, bool b_last
, int64_t i_length
)
1329 const size_t i_max
= rtp_mtu (id
); /* payload max in one packet */
1335 if( i_data
<= i_max
)
1337 /* Single NAL unit packet */
1338 block_t
*out
= block_Alloc( 12 + i_data
);
1340 out
->i_length
= i_length
;
1343 rtp_packetize_common( id
, out
, b_last
, i_pts
);
1345 memcpy( &out
->p_buffer
[12], p_data
, i_data
);
1347 rtp_packetize_send( id
, out
);
1351 const uint16_t i_nal_hdr
= (GetWBE(p_data
) & 0x81FF) | 0x6200 /* 49 */;
1352 const uint8_t i_nal_type
= (p_data
[0] & 0x7E) >> 1;
1354 /* FU-A Fragmentation Unit without interleaving */
1355 const size_t i_count
= ( i_data
-2 + i_max
-3 - 2 ) / (i_max
-3);
1360 for( size_t i
= 0; i
< i_count
; i
++ )
1362 const size_t i_payload
= __MIN( i_data
, i_max
-3 );
1363 block_t
*out
= block_Alloc( 12 + 3 + i_payload
);
1364 out
->i_dts
= i_dts
+ i
* i_length
/ i_count
;
1365 out
->i_length
= i_length
/ i_count
;
1368 rtp_packetize_common( id
, out
, (b_last
&& i_payload
== i_data
),
1371 out
->p_buffer
[12] = i_nal_hdr
>> 8;
1372 out
->p_buffer
[13] = i_nal_hdr
& 0x00FF;
1374 out
->p_buffer
[14] = ( i
== 0 ? 0x80 : 0x00 ) | ( (i
== i_count
-1) ? 0x40 : 0x00 ) | i_nal_type
;
1375 memcpy( &out
->p_buffer
[15], p_data
, i_payload
);
1377 rtp_packetize_send( id
, out
);
1379 i_data
-= i_payload
;
1380 p_data
+= i_payload
;
1386 static int rtp_packetize_h265( sout_stream_id_sys_t
*id
, block_t
*in
)
1388 hxxx_iterator_ctx_t it
;
1389 hxxx_iterator_init( &it
, in
->p_buffer
, in
->i_buffer
, 0 );
1391 const uint8_t *p_nal
;
1393 while( hxxx_annexb_iterate_next( &it
, &p_nal
, &i_nal
) )
1395 rtp_packetize_h265_nal( id
, p_nal
, i_nal
,
1396 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
), in
->i_dts
,
1397 it
.p_head
+ 3 >= it
.p_tail
, in
->i_length
* i_nal
/ in
->i_buffer
);
1404 static int rtp_packetize_amr( sout_stream_id_sys_t
*id
, block_t
*in
)
1406 int i_max
= rtp_mtu (id
) - 2; /* payload max in one packet */
1407 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
1409 uint8_t *p_data
= in
->p_buffer
;
1410 int i_data
= in
->i_buffer
;
1413 /* Only supports octet-aligned mode */
1414 for( i
= 0; i
< i_count
; i
++ )
1416 int i_payload
= __MIN( i_max
, i_data
);
1417 block_t
*out
= block_Alloc( 14 + i_payload
);
1419 /* rtp common header */
1420 rtp_packetize_common( id
, out
, ((i
== i_count
- 1)?1:0),
1421 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1422 /* Payload header */
1423 out
->p_buffer
[12] = 0xF0; /* CMR */
1424 out
->p_buffer
[13] = p_data
[0]&0x7C; /* ToC */ /* FIXME: frame type */
1426 /* FIXME: are we fed multiple frames ? */
1427 memcpy( &out
->p_buffer
[14], p_data
+1, i_payload
-1 );
1429 out
->i_buffer
--; /* FIXME? */
1430 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
1431 out
->i_length
= in
->i_length
/ i_count
;
1433 rtp_packetize_send( id
, out
);
1435 p_data
+= i_payload
;
1436 i_data
-= i_payload
;
1443 static int rtp_packetize_t140( sout_stream_id_sys_t
*id
, block_t
*in
)
1445 const size_t i_max
= rtp_mtu (id
);
1446 const uint8_t *p_data
= in
->p_buffer
;
1447 size_t i_data
= in
->i_buffer
;
1449 for( unsigned i_packet
= 0; i_data
> 0; i_packet
++ )
1451 size_t i_payload
= i_data
;
1453 /* Make sure we stop on an UTF-8 character boundary
1454 * (assuming the input is valid UTF-8) */
1455 if( i_data
> i_max
)
1459 while( ( p_data
[i_payload
] & 0xC0 ) == 0x80 )
1461 if( i_payload
== 0 )
1464 return VLC_SUCCESS
; /* fishy input! */
1470 block_t
*out
= block_Alloc( 12 + i_payload
);
1477 rtp_packetize_common( id
, out
, 0, in
->i_pts
+ i_packet
);
1478 memcpy( out
->p_buffer
+ 12, p_data
, i_payload
);
1480 out
->i_dts
= in
->i_pts
;
1483 rtp_packetize_send( id
, out
);
1485 p_data
+= i_payload
;
1486 i_data
-= i_payload
;
1494 static int rtp_packetize_spx( sout_stream_id_sys_t
*id
, block_t
*in
)
1496 uint8_t *p_buffer
= in
->p_buffer
;
1497 int i_data_size
, i_payload_size
, i_payload_padding
;
1498 i_data_size
= i_payload_size
= in
->i_buffer
;
1499 i_payload_padding
= 0;
1502 if ( in
->i_buffer
> rtp_mtu (id
) )
1509 RFC for Speex in RTP says that each packet must end on an octet
1510 boundary. So, we check to see if the number of bytes % 4 is zero.
1511 If not, we have to add some padding.
1513 This MAY be overkill since packetization is handled elsewhere and
1514 appears to ensure the octet boundary. However, better safe than
1517 if ( i_payload_size
% 4 )
1519 i_payload_padding
= 4 - ( i_payload_size
% 4 );
1520 i_payload_size
+= i_payload_padding
;
1524 Allocate a new RTP p_output block of the appropriate size.
1525 Allow for 12 extra bytes of RTP header.
1527 p_out
= block_Alloc( 12 + i_payload_size
);
1529 if ( i_payload_padding
)
1532 The padding is required to be a zero followed by all 1s.
1534 char c_first_pad
, c_remaining_pad
;
1536 c_remaining_pad
= 0xFF;
1539 Allow for 12 bytes before the i_data_size because
1540 of the expected RTP header added during
1541 rtp_packetize_common.
1543 p_out
->p_buffer
[12 + i_data_size
] = c_first_pad
;
1544 switch (i_payload_padding
)
1547 p_out
->p_buffer
[12 + i_data_size
+ 1] = c_remaining_pad
;
1550 p_out
->p_buffer
[12 + i_data_size
+ 1] = c_remaining_pad
;
1551 p_out
->p_buffer
[12 + i_data_size
+ 2] = c_remaining_pad
;
1556 /* Add the RTP header to our p_output buffer. */
1557 rtp_packetize_common( id
, p_out
, 0,
1558 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1559 /* Copy the Speex payload to the p_output buffer */
1560 memcpy( &p_out
->p_buffer
[12], p_buffer
, i_data_size
);
1562 p_out
->i_dts
= in
->i_dts
;
1563 p_out
->i_length
= in
->i_length
;
1566 /* Queue the buffer for actual transmission. */
1567 rtp_packetize_send( id
, p_out
);
1571 static int rtp_packetize_g726( sout_stream_id_sys_t
*id
, block_t
*in
, int i_pad
)
1573 int i_max
= (rtp_mtu( id
)- 12 + i_pad
- 1) & ~i_pad
;
1574 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
1576 uint8_t *p_data
= in
->p_buffer
;
1577 int i_data
= in
->i_buffer
;
1582 int i_payload
= __MIN( i_max
, i_data
);
1583 block_t
*out
= block_Alloc( 12 + i_payload
);
1585 /* rtp common header */
1586 rtp_packetize_common( id
, out
, 0,
1587 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1589 memcpy( &out
->p_buffer
[12], p_data
, i_payload
);
1591 out
->i_dts
= in
->i_dts
+ i_packet
++ * in
->i_length
/ i_count
;
1592 out
->i_length
= in
->i_length
/ i_count
;
1594 rtp_packetize_send( id
, out
);
1596 p_data
+= i_payload
;
1597 i_data
-= i_payload
;
1604 static int rtp_packetize_g726_16( sout_stream_id_sys_t
*id
, block_t
*in
)
1606 return rtp_packetize_g726( id
, in
, 4 );
1609 static int rtp_packetize_g726_24( sout_stream_id_sys_t
*id
, block_t
*in
)
1611 return rtp_packetize_g726( id
, in
, 8 );
1614 static int rtp_packetize_g726_32( sout_stream_id_sys_t
*id
, block_t
*in
)
1616 return rtp_packetize_g726( id
, in
, 2 );
1619 static int rtp_packetize_g726_40( sout_stream_id_sys_t
*id
, block_t
*in
)
1621 return rtp_packetize_g726( id
, in
, 8 );
1624 #define RTP_VP8_HEADER_SIZE 1
1625 #define RTP_VP8_PAYLOAD_START (12 + RTP_VP8_HEADER_SIZE)
1627 static int rtp_packetize_vp8( sout_stream_id_sys_t
*id
, block_t
*in
)
1629 int i_max
= rtp_mtu (id
) - RTP_VP8_HEADER_SIZE
;
1630 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
1632 uint8_t *p_data
= in
->p_buffer
;
1633 int i_data
= in
->i_buffer
;
1638 return VLC_EGENERIC
;
1641 for( int i
= 0; i
< i_count
; i
++ )
1643 int i_payload
= __MIN( i_max
, i_data
);
1644 block_t
*out
= block_Alloc( RTP_VP8_PAYLOAD_START
+ i_payload
);
1651 /* VP8 payload header */
1652 /* All frames are marked as reference ones */
1654 out
->p_buffer
[12] = 0x10; // partition start
1656 out
->p_buffer
[12] = 0;
1658 /* rtp common header */
1659 rtp_packetize_common( id
, out
, (i
== i_count
- 1),
1660 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1661 memcpy( &out
->p_buffer
[RTP_VP8_PAYLOAD_START
], p_data
, i_payload
);
1663 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
1664 out
->i_length
= in
->i_length
/ i_count
;
1666 rtp_packetize_send( id
, out
);
1668 p_data
+= i_payload
;
1669 i_data
-= i_payload
;
1677 static int rtp_packetize_rawvideo( sout_stream_id_sys_t
*id
, block_t
*in
, vlc_fourcc_t i_format
)
1679 int i_width
, i_height
;
1680 rtp_get_video_geometry( id
, &i_width
, &i_height
);
1681 int i_pgroup
; /* Size of a group of pixels */
1682 int i_xdec
, i_ydec
; /* sub-sampling factor in x and y */
1685 case VLC_CODEC_RGB24
:
1687 i_xdec
= i_ydec
= 1;
1689 case VLC_CODEC_R420
:
1691 i_xdec
= i_ydec
= 2;
1694 vlc_assert_unreachable();
1697 static const int RTP_HEADER_LEN
= 12;
1698 /* each partial or complete line needs a 6 byte header */
1699 const int i_line_header_size
= 6;
1700 const int i_min_line_size
= i_line_header_size
+ i_pgroup
;
1701 uint8_t *p_data
= in
->p_buffer
;
1703 for( uint16_t i_line_number
= 0, i_column
= 0; i_line_number
< i_height
; )
1705 /* Allocate a packet */
1706 int i_payload
= (int)(rtp_mtu (id
) - RTP_HEADER_LEN
);
1707 if( i_payload
<= 0 )
1709 block_Release( in
);
1710 return VLC_EGENERIC
;
1713 block_t
*out
= block_Alloc( RTP_HEADER_LEN
+ i_payload
);
1714 if( unlikely( out
== NULL
) )
1716 block_Release( in
);
1720 /* Do headers first... */
1722 /* Write extended seqnum */
1723 uint8_t *p_outdata
= out
->p_buffer
+ RTP_HEADER_LEN
;
1724 SetWBE( p_outdata
, rtp_get_extended_sequence( id
) );
1728 uint8_t *p_headers
= p_outdata
;
1730 for( uint8_t i_cont
= 0x80; i_cont
&& i_payload
> i_min_line_size
; )
1732 i_payload
-= i_line_header_size
;
1734 int i_pixels
= i_width
- i_column
;
1735 int i_length
= (i_pixels
* i_pgroup
) / i_xdec
;
1737 const bool b_next_line
= i_payload
>= i_length
;
1740 i_pixels
= (i_payload
/ i_pgroup
) * i_xdec
;
1741 i_length
= (i_pixels
* i_pgroup
) / i_xdec
;
1744 i_payload
-= i_length
;
1747 SetWBE( p_outdata
, i_length
);
1750 /* write line number */
1751 /* TODO: support interlaced */
1752 const uint8_t i_field
= 0;
1753 SetWBE( p_outdata
, i_line_number
);
1754 *p_outdata
|= i_field
<< 7;
1757 /* continue if there's still room in the packet and we have more lines */
1758 i_cont
= (i_payload
> i_min_line_size
&& i_line_number
< (i_height
- i_ydec
)) ? 0x80 : 0x00;
1760 /* write offset and continuation marker */
1761 SetWBE( p_outdata
, i_column
);
1762 *p_outdata
|= i_cont
;
1768 i_line_number
+= i_ydec
;
1772 i_column
+= i_pixels
;
1776 /* write the actual video data here */
1777 for( uint8_t i_cont
= 0x80; i_cont
; p_headers
+= i_line_header_size
)
1779 const uint16_t i_length
= GetWBE( p_headers
);
1780 const uint16_t i_lin
= GetWBE( p_headers
+ 2 ) & 0x7fff;
1781 uint16_t i_offs
= GetWBE( p_headers
+ 4 ) & 0x7fff;
1782 i_cont
= p_headers
[4] & 0x80;
1784 if( i_format
== VLC_CODEC_RGB24
)
1786 const int i_ystride
= i_width
* i_pgroup
;
1788 memcpy( p_outdata
, p_data
+ (i_lin
* i_ystride
) + (i_offs
* i_pgroup
), i_length
);
1789 p_outdata
+= i_length
;
1791 else if( i_format
== VLC_CODEC_R420
)
1793 memcpy( p_outdata
, p_data
, i_length
);
1794 p_outdata
+= i_length
;
1797 else vlc_assert_unreachable();
1800 /* rtp common header */
1801 rtp_packetize_common( id
, out
, i_line_number
>= i_height
,
1802 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1804 out
->i_dts
= in
->i_dts
;
1805 out
->i_length
= in
->i_length
;
1807 rtp_packetize_send( id
, out
);
1810 block_Release( in
);
1814 static int rtp_packetize_r420( sout_stream_id_sys_t
*id
, block_t
*in
)
1816 return rtp_packetize_rawvideo( id
, in
, VLC_CODEC_R420
);
1819 static int rtp_packetize_rgb24( sout_stream_id_sys_t
*id
, block_t
*in
)
1821 return rtp_packetize_rawvideo( id
, in
, VLC_CODEC_RGB24
);
1824 static int rtp_packetize_jpeg( sout_stream_id_sys_t
*id
, block_t
*in
)
1826 uint8_t *p_data
= in
->p_buffer
;
1827 int i_data
= in
->i_buffer
;
1828 uint8_t *bufend
= p_data
+ i_data
;
1830 const uint8_t *qtables
= NULL
;
1832 int off
= 0; // fragment offset in frame
1833 int y_sampling_factor
;
1834 // type is set by pixel format (determined by y_sampling_factor):
1837 // += 64 if DRI present
1839 int w
= 0; // Width in multiples of 8
1840 int h
= 0; // Height in multiples of 8
1841 int restart_interval
;
1845 if (GetWBE(p_data
) != 0xffd8)
1850 /* parse the header to get necessary info */
1851 int header_finished
= 0;
1852 while (!header_finished
&& p_data
+ 4 <= bufend
) {
1853 uint16_t marker
= GetWBE(p_data
);
1854 uint8_t *section
= p_data
+ 2;
1855 int section_size
= GetWBE(section
);
1856 uint8_t *section_body
= p_data
+ 4;
1857 if (section
+ section_size
> bufend
)
1860 assert((marker
& 0xff00) == 0xff00);
1863 case 0xffdb /*DQT*/:
1864 if (section_body
[0])
1865 goto error
; // Only 8-bit precision is supported
1867 /* a quantization table is 64 bytes long */
1868 nb_qtables
= section_size
/ 65;
1869 qtables
= section_body
;
1871 case 0xffc0 /*SOF0*/:
1873 int height
= GetWBE(§ion_body
[1]);
1874 int width
= GetWBE(§ion_body
[3]);
1875 if (width
> 2040 || height
> 2040)
1877 // larger than limit supported by RFC 2435
1880 // Round up by 8, divide by 8
1881 w
= ((width
+7)&~7) >> 3;
1882 h
= ((height
+7)&~7) >> 3;
1884 // Get components sampling to determine type
1885 // Y has component ID 1
1886 // Possible configurations of sampling factors:
1887 // Y - 0x22, Cb - 0x11, Cr - 0x11 => yuvj420p
1888 // Y - 0x21, Cb - 0x11, Cr - 0x11 => yuvj422p
1890 // Only 3 components are supported by RFC 2435
1891 if (section_body
[5] != 3) // Number of components
1893 for (int j
= 0; j
< 3; j
++)
1895 if (section_body
[6 + j
* 3] == 1 /* Y */)
1897 y_sampling_factor
= section_body
[6 + j
* 3 + 1];
1899 else if (section_body
[6 + j
* 3 + 1] != 0x11)
1901 // Sampling factor is unsupported by RFC 2435
1907 case 0xffdd /*DRI*/:
1908 restart_interval
= GetWBE(section_body
);
1911 case 0xffda /*SOS*/:
1912 /* SOS is last marker in the header */
1913 header_finished
= 1;
1916 // Step over marker, 16bit length and section body
1917 p_data
+= 2 + section_size
;
1918 i_data
-= 2 + section_size
;
1920 if (!header_finished
)
1925 switch (y_sampling_factor
)
1927 case 0x22: // yuvj420p
1930 case 0x21: // yuvj422p
1934 goto error
; // Sampling format unsupported by RFC 2435
1942 int hdr_size
= 8 + dri_found
* 4;
1943 if (off
== 0 && nb_qtables
)
1944 hdr_size
+= 4 + 64 * nb_qtables
;
1946 int i_payload
= __MIN( i_data
, (int)(rtp_mtu (id
) - hdr_size
) );
1947 if ( i_payload
<= 0 )
1950 block_t
*out
= block_Alloc( 12 + hdr_size
+ i_payload
);
1953 block_Release( in
);
1957 uint8_t *p
= out
->p_buffer
+ 12;
1958 /* set main header */
1959 /* set type-specific=0, set offset in following 24 bits: */
1960 SetDWBE(p
, off
& 0x00ffffff);
1963 *p
++ = 255; // Quant value
1967 // Write restart_marker_hdr if needed
1970 SetWBE(p
, restart_interval
);
1972 // restart_count. Hardcoded same value as in gstreamer implementation
1977 if (off
== 0 && nb_qtables
)
1979 /* set quantization tables header */
1982 SetWBE (p
, 64 * nb_qtables
);
1984 for (int i
= 0; i
< nb_qtables
; i
++)
1986 memcpy (p
, &qtables
[65 * i
+ 1], 64);
1991 /* rtp common header */
1992 rtp_packetize_common( id
, out
, (i_payload
== i_data
),
1993 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1994 memcpy( p
, p_data
, i_payload
);
1996 out
->i_dts
= in
->i_dts
;
1997 out
->i_length
= in
->i_length
;
1999 rtp_packetize_send( id
, out
);
2001 p_data
+= i_payload
;
2002 i_data
-= i_payload
;
2010 return VLC_EGENERIC
;