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
);
578 int i_count
= ( i_data
+ i_max
- 1 ) / i_max
;
580 for( int i
= 0; i
< i_count
; i
++ )
582 int i_payload
= __MIN( i_max
, i_data
);
583 block_t
*out
= block_Alloc( 18 + i_payload
);
585 unsigned fragtype
, numpkts
;
596 else if (i
== i_count
- 1)
601 /* Ident:24, Fragment type:2, Vorbis/Theora Data Type:2, # of pkts:4 */
602 uint32_t header
= ((XIPH_IDENT
& 0xffffff) << 8) |
603 (fragtype
<< 6) | (1 << 4) | numpkts
;
605 /* rtp common header */
606 rtp_packetize_common( id
, out
, 0, i_pts
);
608 SetDWBE( out
->p_buffer
+ 12, header
);
609 SetWBE( out
->p_buffer
+ 16, i_payload
);
610 memcpy( &out
->p_buffer
[18], p_data
, i_payload
);
612 out
->i_buffer
= 18 + i_payload
;
615 rtp_packetize_send( id
, out
);
627 static int rtp_packetize_xiph( sout_stream_id_sys_t
*id
, block_t
*in
)
629 int i_max
= rtp_mtu (id
) - 6; /* payload max in one packet */
630 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
632 uint8_t *p_data
= in
->p_buffer
;
633 int i_data
= in
->i_buffer
;
635 for( int i
= 0; i
< i_count
; i
++ )
637 int i_payload
= __MIN( i_max
, i_data
);
638 block_t
*out
= block_Alloc( 18 + i_payload
);
640 unsigned fragtype
, numpkts
;
643 /* No fragmentation */
653 else if (i
== i_count
- 1)
658 /* Ident:24, Fragment type:2, Vorbis/Theora Data Type:2, # of pkts:4 */
659 uint32_t header
= ((XIPH_IDENT
& 0xffffff) << 8) |
660 (fragtype
<< 6) | (0 << 4) | numpkts
;
662 /* rtp common header */
663 rtp_packetize_common( id
, out
, 0, in
->i_pts
);
665 SetDWBE( out
->p_buffer
+ 12, header
);
666 SetWBE( out
->p_buffer
+ 16, i_payload
);
667 memcpy( &out
->p_buffer
[18], p_data
, i_payload
);
669 out
->i_buffer
= 18 + i_payload
;
670 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
671 out
->i_length
= in
->i_length
/ i_count
;
673 rtp_packetize_send( id
, out
);
682 static int rtp_packetize_mpa( sout_stream_id_sys_t
*id
, block_t
*in
)
684 int i_max
= rtp_mtu (id
) - 4; /* payload max in one packet */
685 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
687 uint8_t *p_data
= in
->p_buffer
;
688 int i_data
= in
->i_buffer
;
691 for( i
= 0; i
< i_count
; i
++ )
693 int i_payload
= __MIN( i_max
, i_data
);
694 block_t
*out
= block_Alloc( 16 + i_payload
);
696 /* rtp common header */
697 rtp_packetize_common( id
, out
, (i
== i_count
- 1)?1:0, in
->i_pts
);
699 SetWBE( out
->p_buffer
+ 12, 0 );
700 /* fragment offset in the current frame */
701 SetWBE( out
->p_buffer
+ 14, i
* i_max
);
702 memcpy( &out
->p_buffer
[16], p_data
, i_payload
);
704 out
->i_buffer
= 16 + i_payload
;
705 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
706 out
->i_length
= in
->i_length
/ i_count
;
708 rtp_packetize_send( id
, out
);
718 static int rtp_packetize_mpv( sout_stream_id_sys_t
*id
, block_t
*in
)
720 int i_max
= rtp_mtu (id
) - 4; /* payload max in one packet */
721 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
723 uint8_t *p_data
= in
->p_buffer
;
724 int i_data
= in
->i_buffer
;
726 int b_sequence_start
= 0;
727 int i_temporal_ref
= 0;
728 int i_picture_coding_type
= 0;
729 int i_fbv
= 0, i_bfc
= 0, i_ffv
= 0, i_ffc
= 0;
730 int b_start_slice
= 0;
732 /* preparse this packet to get some info */
733 if( in
->i_buffer
> 4 )
736 int i_rest
= in
->i_buffer
;
741 ( p
[0] != 0x00 || p
[1] != 0x00 || p
[2] != 0x01 ) )
755 /* sequence start code */
756 b_sequence_start
= 1;
758 else if( *p
== 0x00 && i_rest
>= 4 )
761 i_temporal_ref
= ( p
[1] << 2) |((p
[2]>>6)&0x03);
762 i_picture_coding_type
= (p
[2] >> 3)&0x07;
764 if( i_rest
>= 4 && ( i_picture_coding_type
== 2 ||
765 i_picture_coding_type
== 3 ) )
767 i_ffv
= (p
[3] >> 2)&0x01;
768 i_ffc
= ((p
[3]&0x03) << 1)|((p
[4]>>7)&0x01);
769 if( i_rest
> 4 && i_picture_coding_type
== 3 )
771 i_fbv
= (p
[4]>>6)&0x01;
772 i_bfc
= (p
[4]>>3)&0x07;
776 else if( *p
<= 0xaf )
783 for( i
= 0; i
< i_count
; i
++ )
785 int i_payload
= __MIN( i_max
, i_data
);
786 block_t
*out
= block_Alloc( 16 + i_payload
);
787 /* 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 */
788 uint32_t h
= ( i_temporal_ref
<< 16 )|
789 ( b_sequence_start
<< 13 )|
790 ( b_start_slice
<< 12 )|
791 ( i
== i_count
- 1 ? 1 << 11 : 0 )|
792 ( i_picture_coding_type
<< 8 )|
793 ( i_fbv
<< 7 )|( i_bfc
<< 4 )|( i_ffv
<< 3 )|i_ffc
;
795 /* rtp common header */
796 rtp_packetize_common( id
, out
, (i
== i_count
- 1)?1:0,
797 in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
);
799 SetDWBE( out
->p_buffer
+ 12, h
);
801 memcpy( &out
->p_buffer
[16], p_data
, i_payload
);
803 out
->i_buffer
= 16 + i_payload
;
804 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
805 out
->i_length
= in
->i_length
/ i_count
;
807 rtp_packetize_send( id
, out
);
816 static int rtp_packetize_ac3( sout_stream_id_sys_t
*id
, block_t
*in
)
818 int i_max
= rtp_mtu (id
) - 2; /* payload max in one packet */
819 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
821 uint8_t *p_data
= in
->p_buffer
;
822 int i_data
= in
->i_buffer
;
825 for( i
= 0; i
< i_count
; i
++ )
827 int i_payload
= __MIN( i_max
, i_data
);
828 block_t
*out
= block_Alloc( 14 + i_payload
);
830 /* rtp common header */
831 rtp_packetize_common( id
, out
, (i
== i_count
- 1)?1:0, in
->i_pts
);
833 out
->p_buffer
[12] = 1;
835 out
->p_buffer
[13] = 0x00;
837 memcpy( &out
->p_buffer
[14], p_data
, i_payload
);
839 out
->i_buffer
= 14 + i_payload
;
840 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
841 out
->i_length
= in
->i_length
/ i_count
;
843 rtp_packetize_send( id
, out
);
852 static int rtp_packetize_split( sout_stream_id_sys_t
*id
, block_t
*in
)
854 int i_max
= rtp_mtu (id
); /* payload max in one packet */
855 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
857 uint8_t *p_data
= in
->p_buffer
;
858 int i_data
= in
->i_buffer
;
861 for( i
= 0; i
< i_count
; i
++ )
863 int i_payload
= __MIN( i_max
, i_data
);
864 block_t
*out
= block_Alloc( 12 + i_payload
);
866 /* rtp common header */
867 rtp_packetize_common( id
, out
, (i
== i_count
- 1),
868 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
869 memcpy( &out
->p_buffer
[12], p_data
, i_payload
);
871 out
->i_buffer
= 12 + i_payload
;
872 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
873 out
->i_length
= in
->i_length
/ i_count
;
875 rtp_packetize_send( id
, out
);
884 /* split and convert from little endian to network byte order */
885 static int rtp_packetize_swab( sout_stream_id_sys_t
*id
, block_t
*in
)
887 int i_max
= rtp_mtu (id
); /* payload max in one packet */
888 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
890 uint8_t *p_data
= in
->p_buffer
;
891 int i_data
= in
->i_buffer
;
894 for( i
= 0; i
< i_count
; i
++ )
896 int i_payload
= __MIN( i_max
, i_data
);
897 block_t
*out
= block_Alloc( 12 + i_payload
);
899 /* rtp common header */
900 rtp_packetize_common( id
, out
, (i
== i_count
- 1),
901 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
902 swab( p_data
, out
->p_buffer
+ 12, i_payload
);
904 out
->i_buffer
= 12 + i_payload
;
905 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
906 out
->i_length
= in
->i_length
/ i_count
;
908 rtp_packetize_send( id
, out
);
918 static int rtp_packetize_mp4a_latm( sout_stream_id_sys_t
*id
, block_t
*in
)
920 int i_max
= rtp_mtu (id
) - 2; /* payload max in one packet */
921 int latmhdrsize
= in
->i_buffer
/ 0xff + 1;
922 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
924 uint8_t *p_data
= in
->p_buffer
, *p_header
= NULL
;
925 int i_data
= in
->i_buffer
;
928 for( i
= 0; i
< i_count
; i
++ )
930 int i_payload
= __MIN( i_max
, i_data
);
935 out
= block_Alloc( 12 + latmhdrsize
+ i_payload
);
937 /* rtp common header */
938 rtp_packetize_common( id
, out
, ((i
== i_count
- 1) ? 1 : 0),
939 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
943 int tmp
= in
->i_buffer
;
945 p_header
=out
->p_buffer
+12;
955 memcpy( &out
->p_buffer
[12+latmhdrsize
], p_data
, i_payload
);
957 out
->i_buffer
= 12 + latmhdrsize
+ i_payload
;
958 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
959 out
->i_length
= in
->i_length
/ i_count
;
961 rtp_packetize_send( id
, out
);
970 static int rtp_packetize_mp4a( sout_stream_id_sys_t
*id
, block_t
*in
)
972 int i_max
= rtp_mtu (id
) - 4; /* payload max in one packet */
973 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
975 uint8_t *p_data
= in
->p_buffer
;
976 int i_data
= in
->i_buffer
;
979 for( i
= 0; i
< i_count
; i
++ )
981 int i_payload
= __MIN( i_max
, i_data
);
982 block_t
*out
= block_Alloc( 16 + i_payload
);
984 /* rtp common header */
985 rtp_packetize_common( id
, out
, ((i
== i_count
- 1)?1:0),
986 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
988 /* AU headers length (bits) */
989 out
->p_buffer
[12] = 0;
990 out
->p_buffer
[13] = 2*8;
991 /* for each AU length 13 bits + idx 3bits, */
992 SetWBE( out
->p_buffer
+ 14, (in
->i_buffer
<< 3) | 0 );
994 memcpy( &out
->p_buffer
[16], p_data
, i_payload
);
996 out
->i_buffer
= 16 + i_payload
;
997 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
998 out
->i_length
= in
->i_length
/ i_count
;
1000 rtp_packetize_send( id
, out
);
1002 p_data
+= i_payload
;
1003 i_data
-= i_payload
;
1011 #define RTP_H263_HEADER_SIZE (2) // plen = 0
1012 #define RTP_H263_PAYLOAD_START (14) // plen = 0
1013 static int rtp_packetize_h263( sout_stream_id_sys_t
*id
, block_t
*in
)
1015 uint8_t *p_data
= in
->p_buffer
;
1016 int i_data
= in
->i_buffer
;
1018 int i_max
= rtp_mtu (id
) - RTP_H263_HEADER_SIZE
; /* payload max in one packet */
1021 int b_v_bit
= 0; // no pesky error resilience
1022 int i_plen
= 0; // normally plen=0 for PSC packet
1023 int i_pebit
= 0; // because plen=0
1028 return VLC_EGENERIC
;
1030 if( p_data
[0] || p_data
[1] )
1032 return VLC_EGENERIC
;
1034 /* remove 2 leading 0 bytes */
1037 i_count
= ( i_data
+ i_max
- 1 ) / i_max
;
1039 for( i
= 0; i
< i_count
; i
++ )
1041 int i_payload
= __MIN( i_max
, i_data
);
1042 block_t
*out
= block_Alloc( RTP_H263_PAYLOAD_START
+ i_payload
);
1043 b_p_bit
= (i
== 0) ? 1 : 0;
1044 h
= ( b_p_bit
<< 10 )|
1049 /* rtp common header */
1050 //b_m_bit = 1; // always contains end of frame
1051 rtp_packetize_common( id
, out
, (i
== i_count
- 1)?1:0,
1052 in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
);
1055 SetWBE( out
->p_buffer
+ 12, h
);
1056 memcpy( &out
->p_buffer
[RTP_H263_PAYLOAD_START
], p_data
, i_payload
);
1058 out
->i_buffer
= RTP_H263_PAYLOAD_START
+ i_payload
;
1059 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
1060 out
->i_length
= in
->i_length
/ i_count
;
1062 rtp_packetize_send( id
, out
);
1064 p_data
+= i_payload
;
1065 i_data
-= i_payload
;
1073 rtp_packetize_h264_nal( sout_stream_id_sys_t
*id
,
1074 const uint8_t *p_data
, int i_data
, int64_t i_pts
,
1075 int64_t i_dts
, bool b_last
, int64_t i_length
)
1077 const int i_max
= rtp_mtu (id
); /* payload max in one packet */
1084 i_nal_hdr
= p_data
[3];
1085 i_nal_type
= i_nal_hdr
&0x1f;
1087 /* Skip start code */
1092 if( i_data
<= i_max
)
1094 /* Single NAL unit packet */
1095 block_t
*out
= block_Alloc( 12 + i_data
);
1097 out
->i_length
= i_length
;
1100 rtp_packetize_common( id
, out
, b_last
, i_pts
);
1101 out
->i_buffer
= 12 + i_data
;
1103 memcpy( &out
->p_buffer
[12], p_data
, i_data
);
1105 rtp_packetize_send( id
, out
);
1109 /* FU-A Fragmentation Unit without interleaving */
1110 const int i_count
= ( i_data
-1 + i_max
-2 - 1 ) / (i_max
-2);
1116 for( i
= 0; i
< i_count
; i
++ )
1118 const int i_payload
= __MIN( i_data
, i_max
-2 );
1119 block_t
*out
= block_Alloc( 12 + 2 + i_payload
);
1120 out
->i_dts
= i_dts
+ i
* i_length
/ i_count
;
1121 out
->i_length
= i_length
/ i_count
;
1124 rtp_packetize_common( id
, out
, (b_last
&& i_payload
== i_data
),
1126 out
->i_buffer
= 14 + i_payload
;
1129 out
->p_buffer
[12] = 0x00 | (i_nal_hdr
& 0x60) | 28;
1131 out
->p_buffer
[13] = ( i
== 0 ? 0x80 : 0x00 ) | ( (i
== i_count
-1) ? 0x40 : 0x00 ) | i_nal_type
;
1132 memcpy( &out
->p_buffer
[14], p_data
, i_payload
);
1134 rtp_packetize_send( id
, out
);
1136 i_data
-= i_payload
;
1137 p_data
+= i_payload
;
1143 static int rtp_packetize_h264( sout_stream_id_sys_t
*id
, block_t
*in
)
1145 const uint8_t *p_buffer
= in
->p_buffer
;
1146 int i_buffer
= in
->i_buffer
;
1148 while( i_buffer
> 4 && ( p_buffer
[0] != 0 || p_buffer
[1] != 0 || p_buffer
[2] != 1 ) )
1154 /* Split nal units */
1155 while( i_buffer
> 4 )
1158 int i_size
= i_buffer
;
1159 int i_skip
= i_buffer
;
1161 /* search nal end */
1162 for( i_offset
= 4; i_offset
+2 < i_buffer
; i_offset
++)
1164 if( p_buffer
[i_offset
] == 0 && p_buffer
[i_offset
+1] == 0 && p_buffer
[i_offset
+2] == 1 )
1166 /* we found another startcode */
1167 i_size
= i_offset
- ( p_buffer
[i_offset
-1] == 0 ? 1 : 0);
1172 /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */
1173 rtp_packetize_h264_nal( id
, p_buffer
, i_size
,
1174 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
), in
->i_dts
,
1175 (i_size
>= i_buffer
), in
->i_length
* i_size
/ in
->i_buffer
);
1183 static int rtp_packetize_amr( sout_stream_id_sys_t
*id
, block_t
*in
)
1185 int i_max
= rtp_mtu (id
) - 2; /* payload max in one packet */
1186 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
1188 uint8_t *p_data
= in
->p_buffer
;
1189 int i_data
= in
->i_buffer
;
1192 /* Only supports octet-aligned mode */
1193 for( i
= 0; i
< i_count
; i
++ )
1195 int i_payload
= __MIN( i_max
, i_data
);
1196 block_t
*out
= block_Alloc( 14 + i_payload
);
1198 /* rtp common header */
1199 rtp_packetize_common( id
, out
, ((i
== i_count
- 1)?1:0),
1200 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1201 /* Payload header */
1202 out
->p_buffer
[12] = 0xF0; /* CMR */
1203 out
->p_buffer
[13] = p_data
[0]&0x7C; /* ToC */ /* FIXME: frame type */
1205 /* FIXME: are we fed multiple frames ? */
1206 memcpy( &out
->p_buffer
[14], p_data
+1, i_payload
-1 );
1208 out
->i_buffer
= 14 + i_payload
-1;
1209 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
1210 out
->i_length
= in
->i_length
/ i_count
;
1212 rtp_packetize_send( id
, out
);
1214 p_data
+= i_payload
;
1215 i_data
-= i_payload
;
1221 static int rtp_packetize_t140( sout_stream_id_sys_t
*id
, block_t
*in
)
1223 const size_t i_max
= rtp_mtu (id
);
1224 const uint8_t *p_data
= in
->p_buffer
;
1225 size_t i_data
= in
->i_buffer
;
1227 for( unsigned i_packet
= 0; i_data
> 0; i_packet
++ )
1229 size_t i_payload
= i_data
;
1231 /* Make sure we stop on an UTF-8 character boundary
1232 * (assuming the input is valid UTF-8) */
1233 if( i_data
> i_max
)
1237 while( ( p_data
[i_payload
] & 0xC0 ) == 0x80 )
1239 if( i_payload
== 0 )
1240 return VLC_SUCCESS
; /* fishy input! */
1246 block_t
*out
= block_Alloc( 12 + i_payload
);
1250 rtp_packetize_common( id
, out
, 0, in
->i_pts
+ i_packet
);
1251 memcpy( out
->p_buffer
+ 12, p_data
, i_payload
);
1253 out
->i_buffer
= 12 + i_payload
;
1254 out
->i_dts
= in
->i_pts
;
1257 rtp_packetize_send( id
, out
);
1259 p_data
+= i_payload
;
1260 i_data
-= i_payload
;
1267 static int rtp_packetize_spx( sout_stream_id_sys_t
*id
, block_t
*in
)
1269 uint8_t *p_buffer
= in
->p_buffer
;
1270 int i_data_size
, i_payload_size
, i_payload_padding
;
1271 i_data_size
= i_payload_size
= in
->i_buffer
;
1272 i_payload_padding
= 0;
1275 if ( in
->i_buffer
> rtp_mtu (id
) )
1279 RFC for Speex in RTP says that each packet must end on an octet
1280 boundary. So, we check to see if the number of bytes % 4 is zero.
1281 If not, we have to add some padding.
1283 This MAY be overkill since packetization is handled elsewhere and
1284 appears to ensure the octet boundary. However, better safe than
1287 if ( i_payload_size
% 4 )
1289 i_payload_padding
= 4 - ( i_payload_size
% 4 );
1290 i_payload_size
+= i_payload_padding
;
1294 Allocate a new RTP p_output block of the appropriate size.
1295 Allow for 12 extra bytes of RTP header.
1297 p_out
= block_Alloc( 12 + i_payload_size
);
1299 if ( i_payload_padding
)
1302 The padding is required to be a zero followed by all 1s.
1304 char c_first_pad
, c_remaining_pad
;
1306 c_remaining_pad
= 0xFF;
1309 Allow for 12 bytes before the i_data_size because
1310 of the expected RTP header added during
1311 rtp_packetize_common.
1313 p_out
->p_buffer
[12 + i_data_size
] = c_first_pad
;
1314 switch (i_payload_padding
)
1317 p_out
->p_buffer
[12 + i_data_size
+ 1] = c_remaining_pad
;
1320 p_out
->p_buffer
[12 + i_data_size
+ 1] = c_remaining_pad
;
1321 p_out
->p_buffer
[12 + i_data_size
+ 2] = c_remaining_pad
;
1326 /* Add the RTP header to our p_output buffer. */
1327 rtp_packetize_common( id
, p_out
, 0,
1328 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1329 /* Copy the Speex payload to the p_output buffer */
1330 memcpy( &p_out
->p_buffer
[12], p_buffer
, i_data_size
);
1332 p_out
->i_buffer
= 12 + i_payload_size
;
1333 p_out
->i_dts
= in
->i_dts
;
1334 p_out
->i_length
= in
->i_length
;
1336 /* Queue the buffer for actual transmission. */
1337 rtp_packetize_send( id
, p_out
);
1341 static int rtp_packetize_g726( sout_stream_id_sys_t
*id
, block_t
*in
, int i_pad
)
1343 int i_max
= (rtp_mtu( id
)- 12 + i_pad
- 1) & ~i_pad
;
1344 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
1346 uint8_t *p_data
= in
->p_buffer
;
1347 int i_data
= in
->i_buffer
;
1352 int i_payload
= __MIN( i_max
, i_data
);
1353 block_t
*out
= block_Alloc( 12 + i_payload
);
1355 /* rtp common header */
1356 rtp_packetize_common( id
, out
, 0,
1357 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1359 memcpy( &out
->p_buffer
[12], p_data
, i_payload
);
1361 out
->i_buffer
= 12 + i_payload
;
1362 out
->i_dts
= in
->i_dts
+ i_packet
++ * in
->i_length
/ i_count
;
1363 out
->i_length
= in
->i_length
/ i_count
;
1365 rtp_packetize_send( id
, out
);
1367 p_data
+= i_payload
;
1368 i_data
-= i_payload
;
1373 static int rtp_packetize_g726_16( sout_stream_id_sys_t
*id
, block_t
*in
)
1375 return rtp_packetize_g726( id
, in
, 4 );
1378 static int rtp_packetize_g726_24( sout_stream_id_sys_t
*id
, block_t
*in
)
1380 return rtp_packetize_g726( id
, in
, 8 );
1383 static int rtp_packetize_g726_32( sout_stream_id_sys_t
*id
, block_t
*in
)
1385 return rtp_packetize_g726( id
, in
, 2 );
1388 static int rtp_packetize_g726_40( sout_stream_id_sys_t
*id
, block_t
*in
)
1390 return rtp_packetize_g726( id
, in
, 8 );
1393 #define RTP_VP8_HEADER_SIZE 1
1394 #define RTP_VP8_PAYLOAD_START (12 + RTP_VP8_HEADER_SIZE)
1396 static int rtp_packetize_vp8( sout_stream_id_sys_t
*id
, block_t
*in
)
1398 int i_max
= rtp_mtu (id
) - RTP_VP8_HEADER_SIZE
;
1399 int i_count
= ( in
->i_buffer
+ i_max
- 1 ) / i_max
;
1401 uint8_t *p_data
= in
->p_buffer
;
1402 int i_data
= in
->i_buffer
;
1405 return VLC_EGENERIC
;
1407 for( int i
= 0; i
< i_count
; i
++ )
1409 int i_payload
= __MIN( i_max
, i_data
);
1410 block_t
*out
= block_Alloc( RTP_VP8_PAYLOAD_START
+ i_payload
);
1414 /* VP8 payload header */
1415 /* All frames are marked as reference ones */
1417 out
->p_buffer
[12] = 0x10; // partition start
1419 out
->p_buffer
[12] = 0;
1421 /* rtp common header */
1422 rtp_packetize_common( id
, out
, (i
== i_count
- 1),
1423 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1424 memcpy( &out
->p_buffer
[RTP_VP8_PAYLOAD_START
], p_data
, i_payload
);
1426 out
->i_buffer
= RTP_VP8_PAYLOAD_START
+ i_payload
;
1427 out
->i_dts
= in
->i_dts
+ i
* in
->i_length
/ i_count
;
1428 out
->i_length
= in
->i_length
/ i_count
;
1430 rtp_packetize_send( id
, out
);
1432 p_data
+= i_payload
;
1433 i_data
-= i_payload
;
1439 static int rtp_packetize_jpeg( sout_stream_id_sys_t
*id
, block_t
*in
)
1441 uint8_t *p_data
= in
->p_buffer
;
1442 int i_data
= in
->i_buffer
;
1443 uint8_t *bufend
= p_data
+ i_data
;
1445 const uint8_t *qtables
= NULL
;
1447 int off
= 0; // fragment offset in frame
1448 int y_sampling_factor
;
1449 // type is set by pixel format (determined by y_sampling_factor):
1452 // += 64 if DRI present
1454 int w
= 0; // Width in multiples of 8
1455 int h
= 0; // Height in multiples of 8
1456 int restart_interval
;
1460 if (GetWBE(p_data
) != 0xffd8)
1461 return VLC_EGENERIC
;
1465 /* parse the header to get necessary info */
1466 int header_finished
= 0;
1467 while (!header_finished
&& p_data
+ 4 <= bufend
) {
1468 uint16_t marker
= GetWBE(p_data
);
1469 uint8_t *section
= p_data
+ 2;
1470 int section_size
= GetWBE(section
);
1471 uint8_t *section_body
= p_data
+ 4;
1472 if (section
+ section_size
> bufend
)
1473 return VLC_EGENERIC
;
1475 assert((marker
& 0xff00) == 0xff00);
1478 case 0xffdb /*DQT*/:
1479 if (section_body
[0])
1481 // Only 8-bit precision is supported
1482 return VLC_EGENERIC
;
1485 /* a quantization table is 64 bytes long */
1486 nb_qtables
= section_size
/ 65;
1487 qtables
= section_body
;
1489 case 0xffc0 /*SOF0*/:
1491 int height
= GetWBE(§ion_body
[1]);
1492 int width
= GetWBE(§ion_body
[3]);
1493 if (width
> 2040 || height
> 2040)
1495 // larger than limit supported by RFC 2435
1496 return VLC_EGENERIC
;
1498 // Round up by 8, divide by 8
1499 w
= ((width
+7)&~7) >> 3;
1500 h
= ((height
+7)&~7) >> 3;
1502 // Get components sampling to determine type
1503 // Y has component ID 1
1504 // Possible configurations of sampling factors:
1505 // Y - 0x22, Cb - 0x11, Cr - 0x11 => yuvj420p
1506 // Y - 0x21, Cb - 0x11, Cr - 0x11 => yuvj422p
1508 // Only 3 components are supported by RFC 2435
1509 if (section_body
[5] != 3) // Number of components
1510 return VLC_EGENERIC
;
1511 for (int j
= 0; j
< 3; j
++)
1513 if (section_body
[6 + j
* 3] == 1 /* Y */)
1515 y_sampling_factor
= section_body
[6 + j
* 3 + 1];
1517 else if (section_body
[6 + j
* 3 + 1] != 0x11)
1519 // Sampling factor is unsupported by RFC 2435
1520 return VLC_EGENERIC
;
1525 case 0xffdd /*DRI*/:
1526 restart_interval
= GetWBE(section_body
);
1529 case 0xffda /*SOS*/:
1530 /* SOS is last marker in the header */
1531 header_finished
= 1;
1534 // Step over marker, 16bit length and section body
1535 p_data
+= 2 + section_size
;
1536 i_data
-= 2 + section_size
;
1538 if (!header_finished
)
1539 return VLC_EGENERIC
;
1541 return VLC_EGENERIC
;
1543 switch (y_sampling_factor
)
1545 case 0x22: // yuvj420p
1548 case 0x21: // yuvj422p
1552 // Sampling format unsupported by RFC 2435
1553 return VLC_EGENERIC
;
1561 int hdr_size
= 8 + dri_found
* 4;
1562 if (off
== 0 && nb_qtables
)
1563 hdr_size
+= 4 + 64 * nb_qtables
;
1565 int i_payload
= __MIN( i_data
, (int)(rtp_mtu (id
) - hdr_size
) );
1566 if ( i_payload
<= 0 )
1567 return VLC_EGENERIC
;
1569 block_t
*out
= block_Alloc( 12 + hdr_size
+ i_payload
);
1573 uint8_t *p
= out
->p_buffer
+ 12;
1574 /* set main header */
1575 /* set type-specific=0, set offset in following 24 bits: */
1576 SetDWBE(p
, off
& 0x00ffffff);
1579 *p
++ = 255; // Quant value
1583 // Write restart_marker_hdr if needed
1586 SetWBE(p
, restart_interval
);
1588 // restart_count. Hardcoded same value as in gstreamer implementation
1593 if (off
== 0 && nb_qtables
)
1595 /* set quantization tables header */
1598 SetWBE (p
, 64 * nb_qtables
);
1600 for (int i
= 0; i
< nb_qtables
; i
++)
1602 memcpy (p
, &qtables
[65 * i
+ 1], 64);
1607 /* rtp common header */
1608 rtp_packetize_common( id
, out
, (i_payload
== i_data
),
1609 (in
->i_pts
> VLC_TS_INVALID
? in
->i_pts
: in
->i_dts
) );
1610 memcpy( p
, p_data
, i_payload
);
1612 out
->i_buffer
= 12 + hdr_size
+ i_payload
;
1613 out
->i_dts
= in
->i_dts
;
1614 out
->i_length
= in
->i_length
;
1616 rtp_packetize_send( id
, out
);
1618 p_data
+= i_payload
;
1619 i_data
-= i_payload
;