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>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
29 #include <vlc_common.h>
31 #include <vlc_block.h>
32 #include <vlc_strings.h>
35 #include "../demux/xiph.h"
39 static int rtp_packetize_mpa (sout_stream_id_sys_t
*, block_t
*);
40 static int rtp_packetize_mpv (sout_stream_id_sys_t
*, block_t
*);
41 static int rtp_packetize_ac3 (sout_stream_id_sys_t
*, block_t
*);
42 static int rtp_packetize_split(sout_stream_id_sys_t
*, block_t
*);
43 static int rtp_packetize_swab (sout_stream_id_sys_t
*, block_t
*);
44 static int rtp_packetize_mp4a (sout_stream_id_sys_t
*, block_t
*);
45 static int rtp_packetize_mp4a_latm (sout_stream_id_sys_t
*, block_t
*);
46 static int rtp_packetize_h263 (sout_stream_id_sys_t
*, block_t
*);
47 static int rtp_packetize_h264 (sout_stream_id_sys_t
*, block_t
*);
48 static int rtp_packetize_amr (sout_stream_id_sys_t
*, block_t
*);
49 static int rtp_packetize_spx (sout_stream_id_sys_t
*, block_t
*);
50 static int rtp_packetize_t140 (sout_stream_id_sys_t
*, block_t
*);
51 static int rtp_packetize_g726_16 (sout_stream_id_sys_t
*, block_t
*);
52 static int rtp_packetize_g726_24 (sout_stream_id_sys_t
*, block_t
*);
53 static int rtp_packetize_g726_32 (sout_stream_id_sys_t
*, block_t
*);
54 static int rtp_packetize_g726_40 (sout_stream_id_sys_t
*, block_t
*);
55 static int rtp_packetize_xiph (sout_stream_id_sys_t
*, block_t
*);
56 static int rtp_packetize_vp8 (sout_stream_id_sys_t
*, block_t
*);
57 static int rtp_packetize_jpeg (sout_stream_id_sys_t
*, block_t
*);
59 #define XIPH_IDENT (0)
61 /* Helpers common to xiph codecs (vorbis and theora) */
63 static int rtp_xiph_pack_headers(size_t room
, void *p_extra
, size_t i_extra
,
64 uint8_t **p_buffer
, size_t *i_buffer
,
65 uint8_t *theora_pixel_fmt
)
67 unsigned packet_size
[XIPH_MAX_HEADER_COUNT
];
68 void *packet
[XIPH_MAX_HEADER_COUNT
];
69 unsigned packet_count
;
70 if (xiph_SplitHeaders(packet_size
, packet
, &packet_count
,
76 if (theora_pixel_fmt
!= NULL
)
78 if (packet_size
[0] < 42)
80 *theora_pixel_fmt
= (((uint8_t *)packet
[0])[41] >> 3) & 0x03;
83 unsigned length_size
[2] = { 0, 0 };
84 for (int i
= 0; i
< 2; i
++)
86 unsigned size
= packet_size
[i
];
94 *i_buffer
= room
+ 1 + length_size
[0] + length_size
[1]
95 + packet_size
[0] + packet_size
[1] + packet_size
[2];
96 *p_buffer
= malloc(*i_buffer
);
97 if (*p_buffer
== NULL
)
100 uint8_t *p
= *p_buffer
+ room
;
101 /* Number of headers */
104 for (int i
= 0; i
< 2; i
++)
106 unsigned size
= length_size
[i
];
109 *p
= (packet_size
[i
] >> (7 * (size
- 1))) & 0x7f;
115 for (int i
= 0; i
< 3; i
++)
117 memcpy(p
, packet
[i
], packet_size
[i
]);
124 static char *rtp_xiph_b64_oob_config(void *p_extra
, size_t i_extra
,
125 uint8_t *theora_pixel_fmt
)
129 if (rtp_xiph_pack_headers(9, p_extra
, i_extra
, &p_buffer
, &i_buffer
,
130 theora_pixel_fmt
) != VLC_SUCCESS
)
133 /* Number of packed headers */
134 SetDWBE(p_buffer
, 1);
136 uint32_t ident
= XIPH_IDENT
;
137 SetWBE(p_buffer
+ 4, ident
>> 8);
138 p_buffer
[6] = ident
& 0xff;
140 SetWBE(p_buffer
+ 7, i_buffer
);
142 char *config
= vlc_b64_encode_binary(p_buffer
, i_buffer
);
147 static void sprintf_hexa( char *s
, uint8_t *p_data
, int i_data
)
149 static const char hex
[16] = "0123456789abcdef";
151 for( int i
= 0; i
< i_data
; i
++ )
153 s
[2*i
+0] = hex
[(p_data
[i
]>>4)&0xf];
154 s
[2*i
+1] = hex
[(p_data
[i
] )&0xf];
159 /* TODO: make this into something more clever than a big switch? */
160 int rtp_get_fmt( vlc_object_t
*obj
, es_format_t
*p_fmt
, const char *mux
,
161 rtp_format_t
*rtp_fmt
)
163 assert( p_fmt
!= NULL
|| mux
!= NULL
);
165 /* Dynamic payload type. Payload types are scoped to the RTP
166 * session, and we put each ES in its own session, so no risk of
168 rtp_fmt
->payload_type
= 96;
169 rtp_fmt
->cat
= mux
!= NULL
? VIDEO_ES
: p_fmt
->i_cat
;
170 if( rtp_fmt
->cat
== AUDIO_ES
)
172 rtp_fmt
->clock_rate
= p_fmt
->audio
.i_rate
;
173 rtp_fmt
->channels
= p_fmt
->audio
.i_channels
;
176 rtp_fmt
->clock_rate
= 90000; /* most common case for video */
177 /* Stream bitrate in kbps */
178 rtp_fmt
->bitrate
= p_fmt
!= NULL
? p_fmt
->i_bitrate
/1000 : 0;
179 rtp_fmt
->fmtp
= NULL
;
183 if( strncmp( mux
, "ts", 2 ) == 0 )
185 rtp_fmt
->payload_type
= 33;
186 rtp_fmt
->ptname
= "MP2T";
189 rtp_fmt
->ptname
= "MP2P";
193 switch( p_fmt
->i_codec
)
195 case VLC_CODEC_MULAW
:
196 if( p_fmt
->audio
.i_channels
== 1 && p_fmt
->audio
.i_rate
== 8000 )
197 rtp_fmt
->payload_type
= 0;
198 rtp_fmt
->ptname
= "PCMU";
199 rtp_fmt
->pf_packetize
= rtp_packetize_split
;
202 if( p_fmt
->audio
.i_channels
== 1 && p_fmt
->audio
.i_rate
== 8000 )
203 rtp_fmt
->payload_type
= 8;
204 rtp_fmt
->ptname
= "PCMA";
205 rtp_fmt
->pf_packetize
= rtp_packetize_split
;
209 if( p_fmt
->audio
.i_channels
== 1 && p_fmt
->audio
.i_rate
== 44100 )
211 rtp_fmt
->payload_type
= 11;
213 else if( p_fmt
->audio
.i_channels
== 2 &&
214 p_fmt
->audio
.i_rate
== 44100 )
216 rtp_fmt
->payload_type
= 10;
218 rtp_fmt
->ptname
= "L16";
219 if( p_fmt
->i_codec
== VLC_CODEC_S16B
)
220 rtp_fmt
->pf_packetize
= rtp_packetize_split
;
222 rtp_fmt
->pf_packetize
= rtp_packetize_swab
;
225 rtp_fmt
->ptname
= "L8";
226 rtp_fmt
->pf_packetize
= rtp_packetize_split
;
229 rtp_fmt
->ptname
= "L24";
230 rtp_fmt
->pf_packetize
= rtp_packetize_split
;
233 rtp_fmt
->payload_type
= 14;
234 rtp_fmt
->ptname
= "MPA";
235 rtp_fmt
->clock_rate
= 90000; /* not 44100 */
236 rtp_fmt
->pf_packetize
= rtp_packetize_mpa
;
239 rtp_fmt
->payload_type
= 32;
240 rtp_fmt
->ptname
= "MPV";
241 rtp_fmt
->pf_packetize
= rtp_packetize_mpv
;
243 case VLC_CODEC_ADPCM_G726
:
244 switch( p_fmt
->i_bitrate
/ 1000 )
247 rtp_fmt
->ptname
= "G726-16";
248 rtp_fmt
->pf_packetize
= rtp_packetize_g726_16
;
251 rtp_fmt
->ptname
= "G726-24";
252 rtp_fmt
->pf_packetize
= rtp_packetize_g726_24
;
255 rtp_fmt
->ptname
= "G726-32";
256 rtp_fmt
->pf_packetize
= rtp_packetize_g726_32
;
259 rtp_fmt
->ptname
= "G726-40";
260 rtp_fmt
->pf_packetize
= rtp_packetize_g726_40
;
263 msg_Err( obj
, "cannot add this stream (unsupported "
264 "G.726 bit rate: %u)", p_fmt
->i_bitrate
);
269 rtp_fmt
->ptname
= "ac3";
270 rtp_fmt
->pf_packetize
= rtp_packetize_ac3
;
273 rtp_fmt
->ptname
= "H263-1998";
274 rtp_fmt
->pf_packetize
= rtp_packetize_h263
;
277 rtp_fmt
->ptname
= "H264";
278 rtp_fmt
->pf_packetize
= rtp_packetize_h264
;
279 rtp_fmt
->fmtp
= NULL
;
281 if( p_fmt
->i_extra
> 0 )
283 uint8_t *p_buffer
= p_fmt
->p_extra
;
284 int i_buffer
= p_fmt
->i_extra
;
285 char *p_64_sps
= NULL
;
286 char *p_64_pps
= NULL
;
289 while( i_buffer
> 4 )
294 while( p_buffer
[0] != 0 || p_buffer
[1] != 0 ||
299 if( i_buffer
== 0 ) break;
302 if( i_buffer
< 4 || memcmp(p_buffer
, "\x00\x00\x01", 3 ) )
304 msg_Dbg( obj
, "No startcode found..");
310 const int i_nal_type
= p_buffer
[0]&0x1f;
312 msg_Dbg( obj
, "we found a startcode for NAL with TYPE:%d", i_nal_type
);
315 for( i_offset
= 0; i_offset
+2 < i_buffer
; i_offset
++)
317 if( !memcmp(p_buffer
+ i_offset
, "\x00\x00\x01", 3 ) )
319 /* we found another startcode */
320 while( i_offset
> 0 && 0 == p_buffer
[ i_offset
- 1 ] )
329 msg_Dbg( obj
, "No-info found in nal ");
333 if( i_nal_type
== 7 )
336 p_64_sps
= vlc_b64_encode_binary( p_buffer
, i_size
);
337 /* XXX: nothing ensures that i_size >= 4 ?? */
338 sprintf_hexa( hexa
, &p_buffer
[1], 3 );
340 else if( i_nal_type
== 8 )
343 p_64_pps
= vlc_b64_encode_binary( p_buffer
, i_size
);
349 if( p_64_sps
&& p_64_pps
&&
350 ( asprintf( &rtp_fmt
->fmtp
,
351 "packetization-mode=1;profile-level-id=%s;"
352 "sprop-parameter-sets=%s,%s;", hexa
, p_64_sps
,
354 rtp_fmt
->fmtp
= NULL
;
358 if( rtp_fmt
->fmtp
== NULL
)
359 rtp_fmt
->fmtp
= strdup( "packetization-mode=1" );
364 rtp_fmt
->ptname
= "MP4V-ES";
365 rtp_fmt
->pf_packetize
= rtp_packetize_split
;
366 if( p_fmt
->i_extra
> 0 )
368 char hexa
[2*p_fmt
->i_extra
+1];
369 sprintf_hexa( hexa
, p_fmt
->p_extra
, p_fmt
->i_extra
);
370 if( asprintf( &rtp_fmt
->fmtp
,
371 "profile-level-id=3; config=%s;", hexa
) == -1 )
372 rtp_fmt
->fmtp
= NULL
;
378 if( ! var_InheritBool( obj
, "sout-rtp-mp4a-latm" ) )
380 char hexa
[2*p_fmt
->i_extra
+1];
382 rtp_fmt
->ptname
= "mpeg4-generic";
383 rtp_fmt
->pf_packetize
= rtp_packetize_mp4a
;
384 sprintf_hexa( hexa
, p_fmt
->p_extra
, p_fmt
->i_extra
);
385 if( asprintf( &rtp_fmt
->fmtp
,
386 "streamtype=5; profile-level-id=15; "
387 "mode=AAC-hbr; config=%s; SizeLength=13; "
388 "IndexLength=3; IndexDeltaLength=3; Profile=1;",
390 rtp_fmt
->fmtp
= NULL
;
396 unsigned char config
[6];
397 unsigned int aacsrates
[15] = {
398 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
399 16000, 12000, 11025, 8000, 7350, 0, 0 };
401 for( i
= 0; i
< 15; i
++ )
402 if( p_fmt
->audio
.i_rate
== aacsrates
[i
] )
408 config
[3]=p_fmt
->audio
.i_channels
<<4;
412 rtp_fmt
->ptname
= "MP4A-LATM";
413 rtp_fmt
->pf_packetize
= rtp_packetize_mp4a_latm
;
414 sprintf_hexa( hexa
, config
, 6 );
415 if( asprintf( &rtp_fmt
->fmtp
, "profile-level-id=15; "
416 "object=2; cpresent=0; config=%s", hexa
) == -1 )
417 rtp_fmt
->fmtp
= NULL
;
421 case VLC_CODEC_AMR_NB
:
422 rtp_fmt
->ptname
= "AMR";
423 rtp_fmt
->fmtp
= strdup( "octet-align=1" );
424 rtp_fmt
->pf_packetize
= rtp_packetize_amr
;
426 case VLC_CODEC_AMR_WB
:
427 rtp_fmt
->ptname
= "AMR-WB";
428 rtp_fmt
->fmtp
= strdup( "octet-align=1" );
429 rtp_fmt
->pf_packetize
= rtp_packetize_amr
;
431 case VLC_CODEC_SPEEX
:
432 rtp_fmt
->ptname
= "SPEEX";
433 rtp_fmt
->pf_packetize
= rtp_packetize_spx
;
435 case VLC_CODEC_VORBIS
:
436 rtp_fmt
->ptname
= "vorbis";
437 rtp_fmt
->pf_packetize
= rtp_packetize_xiph
;
438 if( p_fmt
->i_extra
> 0 )
440 rtp_fmt
->fmtp
= NULL
;
441 char *config
= rtp_xiph_b64_oob_config(p_fmt
->p_extra
,
442 p_fmt
->i_extra
, NULL
);
445 if( asprintf( &rtp_fmt
->fmtp
,
446 "configuration=%s;", config
) == -1 )
447 rtp_fmt
->fmtp
= NULL
;
451 case VLC_CODEC_THEORA
:
452 rtp_fmt
->ptname
= "theora";
453 rtp_fmt
->pf_packetize
= rtp_packetize_xiph
;
454 if( p_fmt
->i_extra
> 0 )
456 rtp_fmt
->fmtp
= NULL
;
457 uint8_t pixel_fmt
, c1
, c2
;
458 char *config
= rtp_xiph_b64_oob_config(p_fmt
->p_extra
,
486 if( asprintf( &rtp_fmt
->fmtp
,
487 "sampling=YCbCr-4:%d:%d; width=%d; height=%d; "
488 "delivery-method=inline; configuration=%s; "
489 "delivery-method=in_band;", c1
, c2
,
490 p_fmt
->video
.i_width
, p_fmt
->video
.i_height
,
492 rtp_fmt
->fmtp
= NULL
;
496 case VLC_CODEC_ITU_T140
:
497 rtp_fmt
->ptname
= "t140" ;
498 rtp_fmt
->clock_rate
= 1000;
499 rtp_fmt
->pf_packetize
= rtp_packetize_t140
;
502 rtp_fmt
->payload_type
= 3;
503 rtp_fmt
->ptname
= "GSM";
504 rtp_fmt
->pf_packetize
= rtp_packetize_split
;
507 if (p_fmt
->audio
.i_channels
> 2)
509 msg_Err( obj
, "Multistream opus not supported in RTP"
510 " (having %d channels input)",
511 p_fmt
->audio
.i_channels
);
514 rtp_fmt
->ptname
= "opus";
515 rtp_fmt
->pf_packetize
= rtp_packetize_split
;
516 rtp_fmt
->clock_rate
= 48000;
517 rtp_fmt
->channels
= 2;
518 if (p_fmt
->audio
.i_channels
== 2)
519 rtp_fmt
->fmtp
= strdup( "sprop-stereo=1" );
522 rtp_fmt
->ptname
= "VP8";
523 rtp_fmt
->pf_packetize
= rtp_packetize_vp8
;
527 rtp_fmt
->ptname
= "JPEG";
528 rtp_fmt
->payload_type
= 26;
529 rtp_fmt
->pf_packetize
= rtp_packetize_jpeg
;
533 msg_Err( obj
, "cannot add this stream (unsupported "
534 "codec: %4.4s)", (char*)&p_fmt
->i_codec
);
543 rtp_packetize_h264_nal( sout_stream_id_sys_t
*id
,
544 const uint8_t *p_data
, int i_data
, int64_t i_pts
,
545 int64_t i_dts
, bool b_last
, int64_t i_length
);
547 int rtp_packetize_xiph_config( sout_stream_id_sys_t
*id
, const char *fmtp
,
553 /* extract base64 configuration from fmtp */
554 char *start
= strstr(fmtp
, "configuration=");
555 assert(start
!= NULL
);
556 start
+= sizeof("configuration=") - 1;
557 char *end
= strchr(start
, ';');
559 size_t len
= end
- start
;
561 memcpy(b64
, start
, len
);
564 int i_max
= rtp_mtu (id
) - 6; /* payload max in one packet */
566 uint8_t *p_orig
, *p_data
;
569 i_data
= vlc_b64_decode_binary(&p_orig
, b64
);
576 int i_count
= ( i_data
+ i_max
- 1 ) / i_max
;
578 for( int i
= 0; i
< i_count
; i
++ )
580 int i_payload
= __MIN( i_max
, i_data
);
581 block_t
*out
= block_Alloc( 18 + i_payload
);
583 unsigned fragtype
, numpkts
;
594 else if (i
== i_count
- 1)
599 /* Ident:24, Fragment type:2, Vorbis/Theora Data Type:2, # of pkts:4 */
600 uint32_t header
= ((XIPH_IDENT
& 0xffffff) << 8) |
601 (fragtype
<< 6) | (1 << 4) | numpkts
;
603 /* rtp common header */
604 rtp_packetize_common( id
, out
, 0, i_pts
);
606 SetDWBE( out
->p_buffer
+ 12, header
);
607 SetWBE( out
->p_buffer
+ 16, i_payload
);
608 memcpy( &out
->p_buffer
[18], p_data
, i_payload
);
610 out
->i_buffer
= 18 + i_payload
;
613 rtp_packetize_send( id
, out
);
625 static int rtp_packetize_xiph( sout_stream_id_sys_t
*id
, block_t
*in
)
627 int i_max
= rtp_mtu (id
) - 6; /* payload max in one packet */
628 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
630 uint8_t *p_data
= in
->p_buffer
;
631 int i_data
= in
->i_buffer
;
633 for( int i
= 0; i
< i_count
; i
++ )
635 int i_payload
= __MIN( i_max
, i_data
);
636 block_t
*out
= block_Alloc( 18 + i_payload
);
638 unsigned fragtype
, numpkts
;
641 /* No fragmentation */
651 else if (i
== i_count
- 1)
656 /* Ident:24, Fragment type:2, Vorbis/Theora Data Type:2, # of pkts:4 */
657 uint32_t header
= ((XIPH_IDENT
& 0xffffff) << 8) |
658 (fragtype
<< 6) | (0 << 4) | numpkts
;
660 /* rtp common header */
661 rtp_packetize_common( id
, out
, 0, in
->i_pts
);
663 SetDWBE( out
->p_buffer
+ 12, header
);
664 SetWBE( out
->p_buffer
+ 16, i_payload
);
665 memcpy( &out
->p_buffer
[18], p_data
, i_payload
);
667 out
->i_buffer
= 18 + i_payload
;
668 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
669 out
->i_length
= in
->i_length
/ i_count
;
671 rtp_packetize_send( id
, out
);
680 static int rtp_packetize_mpa( sout_stream_id_sys_t
*id
, block_t
*in
)
682 int i_max
= rtp_mtu (id
) - 4; /* payload max in one packet */
683 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
685 uint8_t *p_data
= in
->p_buffer
;
686 int i_data
= in
->i_buffer
;
689 for( i
= 0; i
< i_count
; i
++ )
691 int i_payload
= __MIN( i_max
, i_data
);
692 block_t
*out
= block_Alloc( 16 + i_payload
);
694 /* rtp common header */
695 rtp_packetize_common( id
, out
, (i
== i_count
- 1)?1:0, in
->i_pts
);
697 SetWBE( out
->p_buffer
+ 12, 0 );
698 /* fragment offset in the current frame */
699 SetWBE( out
->p_buffer
+ 14, i
* i_max
);
700 memcpy( &out
->p_buffer
[16], p_data
, i_payload
);
702 out
->i_buffer
= 16 + i_payload
;
703 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
704 out
->i_length
= in
->i_length
/ i_count
;
706 rtp_packetize_send( id
, out
);
716 static int rtp_packetize_mpv( sout_stream_id_sys_t
*id
, block_t
*in
)
718 int i_max
= rtp_mtu (id
) - 4; /* payload max in one packet */
719 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
721 uint8_t *p_data
= in
->p_buffer
;
722 int i_data
= in
->i_buffer
;
724 int b_sequence_start
= 0;
725 int i_temporal_ref
= 0;
726 int i_picture_coding_type
= 0;
727 int i_fbv
= 0, i_bfc
= 0, i_ffv
= 0, i_ffc
= 0;
728 int b_start_slice
= 0;
730 /* preparse this packet to get some info */
731 if( in
->i_buffer
> 4 )
734 int i_rest
= in
->i_buffer
;
739 ( p
[0] != 0x00 || p
[1] != 0x00 || p
[2] != 0x01 ) )
753 /* sequence start code */
754 b_sequence_start
= 1;
756 else if( *p
== 0x00 && i_rest
>= 4 )
759 i_temporal_ref
= ( p
[1] << 2) |((p
[2]>>6)&0x03);
760 i_picture_coding_type
= (p
[2] >> 3)&0x07;
762 if( i_rest
>= 4 && ( i_picture_coding_type
== 2 ||
763 i_picture_coding_type
== 3 ) )
765 i_ffv
= (p
[3] >> 2)&0x01;
766 i_ffc
= ((p
[3]&0x03) << 1)|((p
[4]>>7)&0x01);
767 if( i_rest
> 4 && i_picture_coding_type
== 3 )
769 i_fbv
= (p
[4]>>6)&0x01;
770 i_bfc
= (p
[4]>>3)&0x07;
774 else if( *p
<= 0xaf )
781 for( i
= 0; i
< i_count
; i
++ )
783 int i_payload
= __MIN( i_max
, i_data
);
784 block_t
*out
= block_Alloc( 16 + i_payload
);
785 /* 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 */
786 uint32_t h
= ( i_temporal_ref
<< 16 )|
787 ( b_sequence_start
<< 13 )|
788 ( b_start_slice
<< 12 )|
789 ( i
== i_count
- 1 ? 1 << 11 : 0 )|
790 ( i_picture_coding_type
<< 8 )|
791 ( i_fbv
<< 7 )|( i_bfc
<< 4 )|( i_ffv
<< 3 )|i_ffc
;
793 /* rtp common header */
794 rtp_packetize_common( id
, out
, (i
== i_count
- 1)?1:0,
795 in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
);
797 SetDWBE( out
->p_buffer
+ 12, h
);
799 memcpy( &out
->p_buffer
[16], p_data
, i_payload
);
801 out
->i_buffer
= 16 + i_payload
;
802 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
803 out
->i_length
= in
->i_length
/ i_count
;
805 rtp_packetize_send( id
, out
);
814 static int rtp_packetize_ac3( sout_stream_id_sys_t
*id
, block_t
*in
)
816 int i_max
= rtp_mtu (id
) - 2; /* payload max in one packet */
817 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
819 uint8_t *p_data
= in
->p_buffer
;
820 int i_data
= in
->i_buffer
;
823 for( i
= 0; i
< i_count
; i
++ )
825 int i_payload
= __MIN( i_max
, i_data
);
826 block_t
*out
= block_Alloc( 14 + i_payload
);
828 /* rtp common header */
829 rtp_packetize_common( id
, out
, (i
== i_count
- 1)?1:0, in
->i_pts
);
831 out
->p_buffer
[12] = 1;
833 out
->p_buffer
[13] = 0x00;
835 memcpy( &out
->p_buffer
[14], p_data
, i_payload
);
837 out
->i_buffer
= 14 + i_payload
;
838 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
839 out
->i_length
= in
->i_length
/ i_count
;
841 rtp_packetize_send( id
, out
);
850 static int rtp_packetize_split( sout_stream_id_sys_t
*id
, block_t
*in
)
852 int i_max
= rtp_mtu (id
); /* payload max in one packet */
853 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
855 uint8_t *p_data
= in
->p_buffer
;
856 int i_data
= in
->i_buffer
;
859 for( i
= 0; i
< i_count
; i
++ )
861 int i_payload
= __MIN( i_max
, i_data
);
862 block_t
*out
= block_Alloc( 12 + i_payload
);
864 /* rtp common header */
865 rtp_packetize_common( id
, out
, (i
== i_count
- 1),
866 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
867 memcpy( &out
->p_buffer
[12], p_data
, i_payload
);
869 out
->i_buffer
= 12 + i_payload
;
870 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
871 out
->i_length
= in
->i_length
/ i_count
;
873 rtp_packetize_send( id
, out
);
882 /* split and convert from little endian to network byte order */
883 static int rtp_packetize_swab( sout_stream_id_sys_t
*id
, block_t
*in
)
885 int i_max
= rtp_mtu (id
); /* payload max in one packet */
886 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
888 uint8_t *p_data
= in
->p_buffer
;
889 int i_data
= in
->i_buffer
;
892 for( i
= 0; i
< i_count
; i
++ )
894 int i_payload
= __MIN( i_max
, i_data
);
895 block_t
*out
= block_Alloc( 12 + i_payload
);
897 /* rtp common header */
898 rtp_packetize_common( id
, out
, (i
== i_count
- 1),
899 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
900 swab( p_data
, out
->p_buffer
+ 12, i_payload
);
902 out
->i_buffer
= 12 + i_payload
;
903 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
904 out
->i_length
= in
->i_length
/ i_count
;
906 rtp_packetize_send( id
, out
);
916 static int rtp_packetize_mp4a_latm( sout_stream_id_sys_t
*id
, block_t
*in
)
918 int i_max
= rtp_mtu (id
) - 2; /* payload max in one packet */
919 int latmhdrsize
= in
->i_buffer
/ 0xff + 1;
920 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
922 uint8_t *p_data
= in
->p_buffer
, *p_header
= NULL
;
923 int i_data
= in
->i_buffer
;
926 for( i
= 0; i
< i_count
; i
++ )
928 int i_payload
= __MIN( i_max
, i_data
);
933 out
= block_Alloc( 12 + latmhdrsize
+ i_payload
);
935 /* rtp common header */
936 rtp_packetize_common( id
, out
, ((i
== i_count
- 1) ? 1 : 0),
937 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
941 int tmp
= in
->i_buffer
;
943 p_header
=out
->p_buffer
+12;
953 memcpy( &out
->p_buffer
[12+latmhdrsize
], p_data
, i_payload
);
955 out
->i_buffer
= 12 + latmhdrsize
+ i_payload
;
956 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
957 out
->i_length
= in
->i_length
/ i_count
;
959 rtp_packetize_send( id
, out
);
968 static int rtp_packetize_mp4a( sout_stream_id_sys_t
*id
, block_t
*in
)
970 int i_max
= rtp_mtu (id
) - 4; /* payload max in one packet */
971 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
973 uint8_t *p_data
= in
->p_buffer
;
974 int i_data
= in
->i_buffer
;
977 for( i
= 0; i
< i_count
; i
++ )
979 int i_payload
= __MIN( i_max
, i_data
);
980 block_t
*out
= block_Alloc( 16 + i_payload
);
982 /* rtp common header */
983 rtp_packetize_common( id
, out
, ((i
== i_count
- 1)?1:0),
984 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
986 /* AU headers length (bits) */
987 out
->p_buffer
[12] = 0;
988 out
->p_buffer
[13] = 2*8;
989 /* for each AU length 13 bits + idx 3bits, */
990 SetWBE( out
->p_buffer
+ 14, (in
->i_buffer
<< 3) | 0 );
992 memcpy( &out
->p_buffer
[16], p_data
, i_payload
);
994 out
->i_buffer
= 16 + i_payload
;
995 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
996 out
->i_length
= in
->i_length
/ i_count
;
998 rtp_packetize_send( id
, out
);
1000 p_data
+= i_payload
;
1001 i_data
-= i_payload
;
1009 #define RTP_H263_HEADER_SIZE (2) // plen = 0
1010 #define RTP_H263_PAYLOAD_START (14) // plen = 0
1011 static int rtp_packetize_h263( sout_stream_id_sys_t
*id
, block_t
*in
)
1013 uint8_t *p_data
= in
->p_buffer
;
1014 int i_data
= in
->i_buffer
;
1016 int i_max
= rtp_mtu (id
) - RTP_H263_HEADER_SIZE
; /* payload max in one packet */
1019 int b_v_bit
= 0; // no pesky error resilience
1020 int i_plen
= 0; // normally plen=0 for PSC packet
1021 int i_pebit
= 0; // because plen=0
1026 return VLC_EGENERIC
;
1028 if( p_data
[0] || p_data
[1] )
1030 return VLC_EGENERIC
;
1032 /* remove 2 leading 0 bytes */
1035 i_count
= ( i_data
+ i_max
- 1 ) / i_max
;
1037 for( i
= 0; i
< i_count
; i
++ )
1039 int i_payload
= __MIN( i_max
, i_data
);
1040 block_t
*out
= block_Alloc( RTP_H263_PAYLOAD_START
+ i_payload
);
1041 b_p_bit
= (i
== 0) ? 1 : 0;
1042 h
= ( b_p_bit
<< 10 )|
1047 /* rtp common header */
1048 //b_m_bit = 1; // always contains end of frame
1049 rtp_packetize_common( id
, out
, (i
== i_count
- 1)?1:0,
1050 in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
);
1053 SetWBE( out
->p_buffer
+ 12, h
);
1054 memcpy( &out
->p_buffer
[RTP_H263_PAYLOAD_START
], p_data
, i_payload
);
1056 out
->i_buffer
= RTP_H263_PAYLOAD_START
+ i_payload
;
1057 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
1058 out
->i_length
= in
->i_length
/ i_count
;
1060 rtp_packetize_send( id
, out
);
1062 p_data
+= i_payload
;
1063 i_data
-= i_payload
;
1071 rtp_packetize_h264_nal( sout_stream_id_sys_t
*id
,
1072 const uint8_t *p_data
, int i_data
, int64_t i_pts
,
1073 int64_t i_dts
, bool b_last
, int64_t i_length
)
1075 const int i_max
= rtp_mtu (id
); /* payload max in one packet */
1082 i_nal_hdr
= p_data
[3];
1083 i_nal_type
= i_nal_hdr
&0x1f;
1085 /* Skip start code */
1090 if( i_data
<= i_max
)
1092 /* Single NAL unit packet */
1093 block_t
*out
= block_Alloc( 12 + i_data
);
1095 out
->i_length
= i_length
;
1098 rtp_packetize_common( id
, out
, b_last
, i_pts
);
1099 out
->i_buffer
= 12 + i_data
;
1101 memcpy( &out
->p_buffer
[12], p_data
, i_data
);
1103 rtp_packetize_send( id
, out
);
1107 /* FU-A Fragmentation Unit without interleaving */
1108 const int i_count
= ( i_data
-1 + i_max
-2 - 1 ) / (i_max
-2);
1114 for( i
= 0; i
< i_count
; i
++ )
1116 const int i_payload
= __MIN( i_data
, i_max
-2 );
1117 block_t
*out
= block_Alloc( 12 + 2 + i_payload
);
1118 out
->i_dts
= i_dts
+ i
* i_length
/ i_count
;
1119 out
->i_length
= i_length
/ i_count
;
1122 rtp_packetize_common( id
, out
, (b_last
&& i_payload
== i_data
),
1124 out
->i_buffer
= 14 + i_payload
;
1127 out
->p_buffer
[12] = 0x00 | (i_nal_hdr
& 0x60) | 28;
1129 out
->p_buffer
[13] = ( i
== 0 ? 0x80 : 0x00 ) | ( (i
== i_count
-1) ? 0x40 : 0x00 ) | i_nal_type
;
1130 memcpy( &out
->p_buffer
[14], p_data
, i_payload
);
1132 rtp_packetize_send( id
, out
);
1134 i_data
-= i_payload
;
1135 p_data
+= i_payload
;
1141 static int rtp_packetize_h264( sout_stream_id_sys_t
*id
, block_t
*in
)
1143 const uint8_t *p_buffer
= in
->p_buffer
;
1144 int i_buffer
= in
->i_buffer
;
1146 while( i_buffer
> 4 && ( p_buffer
[0] != 0 || p_buffer
[1] != 0 || p_buffer
[2] != 1 ) )
1152 /* Split nal units */
1153 while( i_buffer
> 4 )
1156 int i_size
= i_buffer
;
1157 int i_skip
= i_buffer
;
1159 /* search nal end */
1160 for( i_offset
= 4; i_offset
+2 < i_buffer
; i_offset
++)
1162 if( p_buffer
[i_offset
] == 0 && p_buffer
[i_offset
+1] == 0 && p_buffer
[i_offset
+2] == 1 )
1164 /* we found another startcode */
1165 i_size
= i_offset
- ( p_buffer
[i_offset
-1] == 0 ? 1 : 0);
1170 /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */
1171 rtp_packetize_h264_nal( id
, p_buffer
, i_size
,
1172 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
), in
->i_dts
,
1173 (i_size
>= i_buffer
), in
->i_length
* i_size
/ in
->i_buffer
);
1181 static int rtp_packetize_amr( sout_stream_id_sys_t
*id
, block_t
*in
)
1183 int i_max
= rtp_mtu (id
) - 2; /* payload max in one packet */
1184 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
1186 uint8_t *p_data
= in
->p_buffer
;
1187 int i_data
= in
->i_buffer
;
1190 /* Only supports octet-aligned mode */
1191 for( i
= 0; i
< i_count
; i
++ )
1193 int i_payload
= __MIN( i_max
, i_data
);
1194 block_t
*out
= block_Alloc( 14 + i_payload
);
1196 /* rtp common header */
1197 rtp_packetize_common( id
, out
, ((i
== i_count
- 1)?1:0),
1198 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1199 /* Payload header */
1200 out
->p_buffer
[12] = 0xF0; /* CMR */
1201 out
->p_buffer
[13] = p_data
[0]&0x7C; /* ToC */ /* FIXME: frame type */
1203 /* FIXME: are we fed multiple frames ? */
1204 memcpy( &out
->p_buffer
[14], p_data
+1, i_payload
-1 );
1206 out
->i_buffer
= 14 + i_payload
-1;
1207 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
1208 out
->i_length
= in
->i_length
/ i_count
;
1210 rtp_packetize_send( id
, out
);
1212 p_data
+= i_payload
;
1213 i_data
-= i_payload
;
1219 static int rtp_packetize_t140( sout_stream_id_sys_t
*id
, block_t
*in
)
1221 const size_t i_max
= rtp_mtu (id
);
1222 const uint8_t *p_data
= in
->p_buffer
;
1223 size_t i_data
= in
->i_buffer
;
1225 for( unsigned i_packet
= 0; i_data
> 0; i_packet
++ )
1227 size_t i_payload
= i_data
;
1229 /* Make sure we stop on an UTF-8 character boundary
1230 * (assuming the input is valid UTF-8) */
1231 if( i_data
> i_max
)
1235 while( ( p_data
[i_payload
] & 0xC0 ) == 0x80 )
1237 if( i_payload
== 0 )
1238 return VLC_SUCCESS
; /* fishy input! */
1244 block_t
*out
= block_Alloc( 12 + i_payload
);
1248 rtp_packetize_common( id
, out
, 0, in
->i_pts
+ i_packet
);
1249 memcpy( out
->p_buffer
+ 12, p_data
, i_payload
);
1251 out
->i_buffer
= 12 + i_payload
;
1252 out
->i_dts
= in
->i_pts
;
1255 rtp_packetize_send( id
, out
);
1257 p_data
+= i_payload
;
1258 i_data
-= i_payload
;
1265 static int rtp_packetize_spx( sout_stream_id_sys_t
*id
, block_t
*in
)
1267 uint8_t *p_buffer
= in
->p_buffer
;
1268 int i_data_size
, i_payload_size
, i_payload_padding
;
1269 i_data_size
= i_payload_size
= in
->i_buffer
;
1270 i_payload_padding
= 0;
1273 if ( in
->i_buffer
> rtp_mtu (id
) )
1277 RFC for Speex in RTP says that each packet must end on an octet
1278 boundary. So, we check to see if the number of bytes % 4 is zero.
1279 If not, we have to add some padding.
1281 This MAY be overkill since packetization is handled elsewhere and
1282 appears to ensure the octet boundary. However, better safe than
1285 if ( i_payload_size
% 4 )
1287 i_payload_padding
= 4 - ( i_payload_size
% 4 );
1288 i_payload_size
+= i_payload_padding
;
1292 Allocate a new RTP p_output block of the appropriate size.
1293 Allow for 12 extra bytes of RTP header.
1295 p_out
= block_Alloc( 12 + i_payload_size
);
1297 if ( i_payload_padding
)
1300 The padding is required to be a zero followed by all 1s.
1302 char c_first_pad
, c_remaining_pad
;
1304 c_remaining_pad
= 0xFF;
1307 Allow for 12 bytes before the i_data_size because
1308 of the expected RTP header added during
1309 rtp_packetize_common.
1311 p_out
->p_buffer
[12 + i_data_size
] = c_first_pad
;
1312 switch (i_payload_padding
)
1315 p_out
->p_buffer
[12 + i_data_size
+ 1] = c_remaining_pad
;
1318 p_out
->p_buffer
[12 + i_data_size
+ 1] = c_remaining_pad
;
1319 p_out
->p_buffer
[12 + i_data_size
+ 2] = c_remaining_pad
;
1324 /* Add the RTP header to our p_output buffer. */
1325 rtp_packetize_common( id
, p_out
, 0,
1326 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1327 /* Copy the Speex payload to the p_output buffer */
1328 memcpy( &p_out
->p_buffer
[12], p_buffer
, i_data_size
);
1330 p_out
->i_buffer
= 12 + i_payload_size
;
1331 p_out
->i_dts
= in
->i_dts
;
1332 p_out
->i_length
= in
->i_length
;
1334 /* Queue the buffer for actual transmission. */
1335 rtp_packetize_send( id
, p_out
);
1339 static int rtp_packetize_g726( sout_stream_id_sys_t
*id
, block_t
*in
, int i_pad
)
1341 int i_max
= (rtp_mtu( id
)- 12 + i_pad
- 1) & ~i_pad
;
1342 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
1344 uint8_t *p_data
= in
->p_buffer
;
1345 int i_data
= in
->i_buffer
;
1350 int i_payload
= __MIN( i_max
, i_data
);
1351 block_t
*out
= block_Alloc( 12 + i_payload
);
1353 /* rtp common header */
1354 rtp_packetize_common( id
, out
, 0,
1355 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1357 memcpy( &out
->p_buffer
[12], p_data
, i_payload
);
1359 out
->i_buffer
= 12 + i_payload
;
1360 out
->i_dts
= in
->i_dts
+ i_packet
++ * in
->i_length
/ i_count
;
1361 out
->i_length
= in
->i_length
/ i_count
;
1363 rtp_packetize_send( id
, out
);
1365 p_data
+= i_payload
;
1366 i_data
-= i_payload
;
1371 static int rtp_packetize_g726_16( sout_stream_id_sys_t
*id
, block_t
*in
)
1373 return rtp_packetize_g726( id
, in
, 4 );
1376 static int rtp_packetize_g726_24( sout_stream_id_sys_t
*id
, block_t
*in
)
1378 return rtp_packetize_g726( id
, in
, 8 );
1381 static int rtp_packetize_g726_32( sout_stream_id_sys_t
*id
, block_t
*in
)
1383 return rtp_packetize_g726( id
, in
, 2 );
1386 static int rtp_packetize_g726_40( sout_stream_id_sys_t
*id
, block_t
*in
)
1388 return rtp_packetize_g726( id
, in
, 8 );
1391 #define RTP_VP8_HEADER_SIZE 1
1392 #define RTP_VP8_PAYLOAD_START (12 + RTP_VP8_HEADER_SIZE)
1394 static int rtp_packetize_vp8( sout_stream_id_sys_t
*id
, block_t
*in
)
1396 int i_max
= rtp_mtu (id
) - RTP_VP8_HEADER_SIZE
;
1397 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
1399 uint8_t *p_data
= in
->p_buffer
;
1400 int i_data
= in
->i_buffer
;
1403 return VLC_EGENERIC
;
1405 for( int i
= 0; i
< i_count
; i
++ )
1407 int i_payload
= __MIN( i_max
, i_data
);
1408 block_t
*out
= block_Alloc( RTP_VP8_PAYLOAD_START
+ i_payload
);
1412 /* VP8 payload header */
1413 /* All frames are marked as reference ones */
1415 out
->p_buffer
[12] = 0x10; // partition start
1417 out
->p_buffer
[12] = 0;
1419 /* rtp common header */
1420 rtp_packetize_common( id
, out
, (i
== i_count
- 1),
1421 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1422 memcpy( &out
->p_buffer
[RTP_VP8_PAYLOAD_START
], p_data
, i_payload
);
1424 out
->i_buffer
= RTP_VP8_PAYLOAD_START
+ i_payload
;
1425 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
1426 out
->i_length
= in
->i_length
/ i_count
;
1428 rtp_packetize_send( id
, out
);
1430 p_data
+= i_payload
;
1431 i_data
-= i_payload
;
1437 static int rtp_packetize_jpeg( sout_stream_id_sys_t
*id
, block_t
*in
)
1439 uint8_t *p_data
= in
->p_buffer
;
1440 int i_data
= in
->i_buffer
;
1441 uint8_t *bufend
= p_data
+ i_data
;
1443 const uint8_t *qtables
= NULL
;
1445 int off
= 0; // fragment offset in frame
1446 int y_sampling_factor
;
1447 // type is set by pixel format (determined by y_sampling_factor):
1450 // += 64 if DRI present
1452 int w
= 0; // Width in multiples of 8
1453 int h
= 0; // Height in multiples of 8
1454 int restart_interval
;
1458 if (GetWBE(p_data
) != 0xffd8)
1459 return VLC_EGENERIC
;
1463 /* parse the header to get necessary info */
1464 int header_finished
= 0;
1465 while (!header_finished
&& p_data
+ 4 <= bufend
) {
1466 uint16_t marker
= GetWBE(p_data
);
1467 uint8_t *section
= p_data
+ 2;
1468 int section_size
= GetWBE(section
);
1469 uint8_t *section_body
= p_data
+ 4;
1470 if (section
+ section_size
> bufend
)
1471 return VLC_EGENERIC
;
1473 assert((marker
& 0xff00) == 0xff00);
1476 case 0xffdb /*DQT*/:
1477 if (section_body
[0])
1479 // Only 8-bit precision is supported
1480 return VLC_EGENERIC
;
1483 /* a quantization table is 64 bytes long */
1484 nb_qtables
= section_size
/ 65;
1485 qtables
= section_body
;
1487 case 0xffc0 /*SOF0*/:
1489 int height
= GetWBE(§ion_body
[1]);
1490 int width
= GetWBE(§ion_body
[3]);
1491 if (width
> 2040 || height
> 2040)
1493 // larger than limit supported by RFC 2435
1494 return VLC_EGENERIC
;
1496 // Round up by 8, divide by 8
1497 w
= ((width
+7)&~7) >> 3;
1498 h
= ((height
+7)&~7) >> 3;
1500 // Get components sampling to determine type
1501 // Y has component ID 1
1502 // Possible configurations of sampling factors:
1503 // Y - 0x22, Cb - 0x11, Cr - 0x11 => yuvj420p
1504 // Y - 0x21, Cb - 0x11, Cr - 0x11 => yuvj422p
1506 // Only 3 components are supported by RFC 2435
1507 if (section_body
[5] != 3) // Number of components
1508 return VLC_EGENERIC
;
1509 for (int j
= 0; j
< 3; j
++)
1511 if (section_body
[6 + j
* 3] == 1 /* Y */)
1513 y_sampling_factor
= section_body
[6 + j
* 3 + 1];
1515 else if (section_body
[6 + j
* 3 + 1] != 0x11)
1517 // Sampling factor is unsupported by RFC 2435
1518 return VLC_EGENERIC
;
1523 case 0xffdd /*DRI*/:
1524 restart_interval
= GetWBE(section_body
);
1527 case 0xffda /*SOS*/:
1528 /* SOS is last marker in the header */
1529 header_finished
= 1;
1532 // Step over marker, 16bit length and section body
1533 p_data
+= 2 + section_size
;
1534 i_data
-= 2 + section_size
;
1536 if (!header_finished
)
1537 return VLC_EGENERIC
;
1539 return VLC_EGENERIC
;
1541 switch (y_sampling_factor
)
1543 case 0x22: // yuvj420p
1546 case 0x21: // yuvj422p
1550 // Sampling format unsupported by RFC 2435
1551 return VLC_EGENERIC
;
1559 int hdr_size
= 8 + dri_found
* 4;
1560 if (off
== 0 && nb_qtables
)
1561 hdr_size
+= 4 + 64 * nb_qtables
;
1563 int i_payload
= __MIN( i_data
, (int)(rtp_mtu (id
) - hdr_size
) );
1564 if ( i_payload
<= 0 )
1565 return VLC_EGENERIC
;
1567 block_t
*out
= block_Alloc( 12 + hdr_size
+ i_payload
);
1571 uint8_t *p
= out
->p_buffer
+ 12;
1572 /* set main header */
1573 /* set type-specific=0, set offset in following 24 bits: */
1574 SetDWBE(p
, off
& 0x00ffffff);
1577 *p
++ = 255; // Quant value
1581 // Write restart_marker_hdr if needed
1584 SetWBE(p
, restart_interval
);
1586 // restart_count. Hardcoded same value as in gstreamer implementation
1591 if (off
== 0 && nb_qtables
)
1593 /* set quantization tables header */
1596 SetWBE (p
, 64 * nb_qtables
);
1598 for (int i
= 0; i
< nb_qtables
; i
++)
1600 memcpy (p
, &qtables
[65 * i
+ 1], 64);
1605 /* rtp common header */
1606 rtp_packetize_common( id
, out
, (i_payload
== i_data
),
1607 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1608 memcpy( p
, p_data
, i_payload
);
1610 out
->i_buffer
= 12 + hdr_size
+ i_payload
;
1611 out
->i_dts
= in
->i_dts
;
1612 out
->i_length
= in
->i_length
;
1614 rtp_packetize_send( id
, out
);
1616 p_data
+= i_payload
;
1617 i_data
-= i_payload
;