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"
41 static int rtp_packetize_mpa (sout_stream_id_sys_t *, block_t *);
42 static int rtp_packetize_mpv (sout_stream_id_sys_t *, block_t *);
43 static int rtp_packetize_ac3 (sout_stream_id_sys_t *, block_t *);
44 static int rtp_packetize_simple(sout_stream_id_sys_t *, block_t *);
45 static int rtp_packetize_split(sout_stream_id_sys_t *, block_t *);
46 static int rtp_packetize_pcm(sout_stream_id_sys_t *, block_t *);
47 static int rtp_packetize_swab (sout_stream_id_sys_t *, block_t *);
48 static int rtp_packetize_mp4a (sout_stream_id_sys_t *, block_t *);
49 static int rtp_packetize_mp4a_latm (sout_stream_id_sys_t *, block_t *);
50 static int rtp_packetize_h263 (sout_stream_id_sys_t *, block_t *);
51 static int rtp_packetize_h264 (sout_stream_id_sys_t *, block_t *);
52 static int rtp_packetize_amr (sout_stream_id_sys_t *, block_t *);
53 static int rtp_packetize_spx (sout_stream_id_sys_t *, block_t *);
54 static int rtp_packetize_t140 (sout_stream_id_sys_t *, block_t *);
55 static int rtp_packetize_g726_16 (sout_stream_id_sys_t *, block_t *);
56 static int rtp_packetize_g726_24 (sout_stream_id_sys_t *, block_t *);
57 static int rtp_packetize_g726_32 (sout_stream_id_sys_t *, block_t *);
58 static int rtp_packetize_g726_40 (sout_stream_id_sys_t *, block_t *);
59 static int rtp_packetize_xiph (sout_stream_id_sys_t *, block_t *);
60 static int rtp_packetize_vp8 (sout_stream_id_sys_t *, block_t *);
61 static int rtp_packetize_jpeg (sout_stream_id_sys_t *, block_t *);
62 static int rtp_packetize_r420 (sout_stream_id_sys_t *, block_t *);
63 static int rtp_packetize_rgb24 (sout_stream_id_sys_t *, block_t *);
65 #define XIPH_IDENT (0)
67 /* Helpers common to xiph codecs (vorbis and theora) */
69 static int rtp_xiph_pack_headers(size_t room, void *p_extra, size_t i_extra,
70 uint8_t **p_buffer, size_t *i_buffer,
71 uint8_t *theora_pixel_fmt)
73 unsigned packet_size[XIPH_MAX_HEADER_COUNT];
74 void *packet[XIPH_MAX_HEADER_COUNT];
75 unsigned packet_count;
76 if (xiph_SplitHeaders(packet_size, packet, &packet_count,
82 if (theora_pixel_fmt != NULL)
84 if (packet_size[0] < 42)
86 *theora_pixel_fmt = (((uint8_t *)packet[0])[41] >> 3) & 0x03;
89 unsigned length_size[2] = { 0, 0 };
90 for (int i = 0; i < 2; i++)
92 unsigned size = packet_size[i];
100 *i_buffer = room + 1 + length_size[0] + length_size[1]
101 + packet_size[0] + packet_size[1] + packet_size[2];
102 *p_buffer = malloc(*i_buffer);
103 if (*p_buffer == NULL)
106 uint8_t *p = *p_buffer + room;
107 /* Number of headers */
110 for (int i = 0; i < 2; i++)
112 unsigned size = length_size[i];
115 *p = (packet_size[i] >> (7 * (size - 1))) & 0x7f;
121 for (int i = 0; i < 3; i++)
123 memcpy(p, packet[i], packet_size[i]);
130 static char *rtp_xiph_b64_oob_config(void *p_extra, size_t i_extra,
131 uint8_t *theora_pixel_fmt)
135 if (rtp_xiph_pack_headers(9, p_extra, i_extra, &p_buffer, &i_buffer,
136 theora_pixel_fmt) != VLC_SUCCESS)
139 /* Number of packed headers */
140 SetDWBE(p_buffer, 1);
142 uint32_t ident = XIPH_IDENT;
143 SetWBE(p_buffer + 4, ident >> 8);
144 p_buffer[6] = ident & 0xff;
146 SetWBE(p_buffer + 7, i_buffer);
148 char *config = vlc_b64_encode_binary(p_buffer, i_buffer);
153 static void sprintf_hexa( char *s, uint8_t *p_data, int i_data )
155 static const char hex[16] = "0123456789abcdef";
157 for( int i = 0; i < i_data; i++ )
159 s[2*i+0] = hex[(p_data[i]>>4)&0xf];
160 s[2*i+1] = hex[(p_data[i] )&0xf];
165 /* TODO: make this into something more clever than a big switch? */
166 int rtp_get_fmt( vlc_object_t *obj, const es_format_t *p_fmt, const char *mux,
167 rtp_format_t *rtp_fmt )
169 assert( p_fmt != NULL || mux != NULL );
171 /* Dynamic payload type. Payload types are scoped to the RTP
172 * session, and we put each ES in its own session, so no risk of
174 rtp_fmt->payload_type = 96;
175 rtp_fmt->cat = mux != NULL ? VIDEO_ES : p_fmt->i_cat;
176 if( rtp_fmt->cat == AUDIO_ES )
178 rtp_fmt->clock_rate = p_fmt->audio.i_rate;
179 rtp_fmt->channels = p_fmt->audio.i_channels;
182 rtp_fmt->clock_rate = 90000; /* most common case for video */
183 /* Stream bitrate in kbps */
184 rtp_fmt->bitrate = p_fmt != NULL ? p_fmt->i_bitrate/1000 : 0;
185 rtp_fmt->fmtp = NULL;
189 if( strncmp( mux, "ts", 2 ) == 0 )
191 rtp_fmt->payload_type = 33;
192 rtp_fmt->ptname = "MP2T";
195 rtp_fmt->ptname = "MP2P";
199 switch( p_fmt->i_codec )
201 case VLC_CODEC_MULAW:
202 if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
203 rtp_fmt->payload_type = 0;
204 rtp_fmt->ptname = "PCMU";
205 rtp_fmt->pf_packetize = rtp_packetize_pcm;
208 if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 8000 )
209 rtp_fmt->payload_type = 8;
210 rtp_fmt->ptname = "PCMA";
211 rtp_fmt->pf_packetize = rtp_packetize_pcm;
215 if( p_fmt->audio.i_channels == 1 && p_fmt->audio.i_rate == 44100 )
217 rtp_fmt->payload_type = 11;
219 else if( p_fmt->audio.i_channels == 2 &&
220 p_fmt->audio.i_rate == 44100 )
222 rtp_fmt->payload_type = 10;
224 rtp_fmt->ptname = "L16";
225 if( p_fmt->i_codec == VLC_CODEC_S16B )
226 rtp_fmt->pf_packetize = rtp_packetize_pcm;
228 rtp_fmt->pf_packetize = rtp_packetize_swab;
231 rtp_fmt->ptname = "L8";
232 rtp_fmt->pf_packetize = rtp_packetize_pcm;
235 rtp_fmt->ptname = "L24";
236 rtp_fmt->pf_packetize = rtp_packetize_pcm;
239 rtp_fmt->payload_type = 14;
240 rtp_fmt->ptname = "MPA";
241 rtp_fmt->clock_rate = 90000; /* not 44100 */
242 rtp_fmt->pf_packetize = rtp_packetize_mpa;
245 rtp_fmt->payload_type = 32;
246 rtp_fmt->ptname = "MPV";
247 rtp_fmt->pf_packetize = rtp_packetize_mpv;
249 case VLC_CODEC_ADPCM_G726:
250 switch( p_fmt->i_bitrate / 1000 )
253 rtp_fmt->ptname = "G726-16";
254 rtp_fmt->pf_packetize = rtp_packetize_g726_16;
257 rtp_fmt->ptname = "G726-24";
258 rtp_fmt->pf_packetize = rtp_packetize_g726_24;
261 rtp_fmt->ptname = "G726-32";
262 rtp_fmt->pf_packetize = rtp_packetize_g726_32;
265 rtp_fmt->ptname = "G726-40";
266 rtp_fmt->pf_packetize = rtp_packetize_g726_40;
269 msg_Err( obj, "cannot add this stream (unsupported "
270 "G.726 bit rate: %u)", p_fmt->i_bitrate );
275 rtp_fmt->ptname = "ac3";
276 rtp_fmt->pf_packetize = rtp_packetize_ac3;
279 rtp_fmt->ptname = "H263-1998";
280 rtp_fmt->pf_packetize = rtp_packetize_h263;
283 rtp_fmt->ptname = "H264";
284 rtp_fmt->pf_packetize = rtp_packetize_h264;
285 rtp_fmt->fmtp = NULL;
287 if( p_fmt->i_extra > 0 )
289 uint8_t *p_buffer = p_fmt->p_extra;
290 int i_buffer = p_fmt->i_extra;
291 char *p_64_sps = NULL;
292 char *p_64_pps = NULL;
295 while( i_buffer > 4 )
300 while( p_buffer[0] != 0 || p_buffer[1] != 0 ||
305 if( i_buffer == 0 ) break;
308 if( i_buffer < 4 || memcmp(p_buffer, "\x00\x00\x01", 3 ) )
310 msg_Dbg( obj, "No startcode found..");
316 const int i_nal_type = p_buffer[0]&0x1f;
318 msg_Dbg( obj, "we found a startcode for NAL with TYPE:%d", i_nal_type );
321 for( i_offset = 0; i_offset+2 < i_buffer ; i_offset++)
323 if( !memcmp(p_buffer + i_offset, "\x00\x00\x01", 3 ) )
325 /* we found another startcode */
326 while( i_offset > 0 && 0 == p_buffer[ i_offset - 1 ] )
335 msg_Dbg( obj, "No-info found in nal ");
339 if( i_nal_type == 7 )
342 p_64_sps = vlc_b64_encode_binary( p_buffer, i_size );
343 /* XXX: nothing ensures that i_size >= 4 ?? */
344 sprintf_hexa( hexa, &p_buffer[1], 3 );
346 else if( i_nal_type == 8 )
349 p_64_pps = vlc_b64_encode_binary( p_buffer, i_size );
355 if( p_64_sps && p_64_pps &&
356 ( asprintf( &rtp_fmt->fmtp,
357 "packetization-mode=1;profile-level-id=%s;"
358 "sprop-parameter-sets=%s,%s;", hexa, p_64_sps,
360 rtp_fmt->fmtp = NULL;
364 if( rtp_fmt->fmtp == NULL )
365 rtp_fmt->fmtp = strdup( "packetization-mode=1" );
370 rtp_fmt->ptname = "MP4V-ES";
371 rtp_fmt->pf_packetize = rtp_packetize_split;
372 if( p_fmt->i_extra > 0 )
374 char hexa[2*p_fmt->i_extra +1];
375 sprintf_hexa( hexa, p_fmt->p_extra, p_fmt->i_extra );
376 if( asprintf( &rtp_fmt->fmtp,
377 "profile-level-id=3; config=%s;", hexa ) == -1 )
378 rtp_fmt->fmtp = NULL;
384 if( ! var_InheritBool( obj, "sout-rtp-mp4a-latm" ) )
386 char hexa[2*p_fmt->i_extra +1];
388 rtp_fmt->ptname = "mpeg4-generic";
389 rtp_fmt->pf_packetize = rtp_packetize_mp4a;
390 sprintf_hexa( hexa, p_fmt->p_extra, p_fmt->i_extra );
391 if( asprintf( &rtp_fmt->fmtp,
392 "streamtype=5; profile-level-id=15; "
393 "mode=AAC-hbr; config=%s; SizeLength=13; "
394 "IndexLength=3; IndexDeltaLength=3; Profile=1;",
396 rtp_fmt->fmtp = NULL;
402 unsigned char config[6];
403 unsigned int aacsrates[15] = {
404 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
405 16000, 12000, 11025, 8000, 7350, 0, 0 };
407 for( i = 0; i < 15; i++ )
408 if( p_fmt->audio.i_rate == aacsrates[i] )
414 config[3]=p_fmt->audio.i_channels<<4;
418 rtp_fmt->ptname = "MP4A-LATM";
419 rtp_fmt->pf_packetize = rtp_packetize_mp4a_latm;
420 sprintf_hexa( hexa, config, 6 );
421 if( asprintf( &rtp_fmt->fmtp, "profile-level-id=15; "
422 "object=2; cpresent=0; config=%s", hexa ) == -1 )
423 rtp_fmt->fmtp = NULL;
427 case VLC_CODEC_AMR_NB:
428 rtp_fmt->ptname = "AMR";
429 rtp_fmt->fmtp = strdup( "octet-align=1" );
430 rtp_fmt->pf_packetize = rtp_packetize_amr;
432 case VLC_CODEC_AMR_WB:
433 rtp_fmt->ptname = "AMR-WB";
434 rtp_fmt->fmtp = strdup( "octet-align=1" );
435 rtp_fmt->pf_packetize = rtp_packetize_amr;
437 case VLC_CODEC_SPEEX:
438 rtp_fmt->ptname = "SPEEX";
439 rtp_fmt->pf_packetize = rtp_packetize_spx;
441 case VLC_CODEC_VORBIS:
442 rtp_fmt->ptname = "vorbis";
443 rtp_fmt->pf_packetize = rtp_packetize_xiph;
444 if( p_fmt->i_extra > 0 )
446 rtp_fmt->fmtp = NULL;
447 char *config = rtp_xiph_b64_oob_config(p_fmt->p_extra,
448 p_fmt->i_extra, NULL);
451 if( asprintf( &rtp_fmt->fmtp,
452 "configuration=%s;", config ) == -1 )
453 rtp_fmt->fmtp = NULL;
457 case VLC_CODEC_THEORA:
458 rtp_fmt->ptname = "theora";
459 rtp_fmt->pf_packetize = rtp_packetize_xiph;
460 if( p_fmt->i_extra > 0 )
462 rtp_fmt->fmtp = NULL;
463 uint8_t pixel_fmt, c1, c2;
464 char *config = rtp_xiph_b64_oob_config(p_fmt->p_extra,
489 vlc_assert_unreachable();
492 if( asprintf( &rtp_fmt->fmtp,
493 "sampling=YCbCr-4:%d:%d; width=%d; height=%d; "
494 "delivery-method=inline; configuration=%s; "
495 "delivery-method=in_band;", c1, c2,
496 p_fmt->video.i_width, p_fmt->video.i_height,
498 rtp_fmt->fmtp = NULL;
502 case VLC_CODEC_ITU_T140:
503 rtp_fmt->ptname = "t140" ;
504 rtp_fmt->clock_rate = 1000;
505 rtp_fmt->pf_packetize = rtp_packetize_t140;
508 rtp_fmt->payload_type = 3;
509 rtp_fmt->ptname = "GSM";
510 rtp_fmt->pf_packetize = rtp_packetize_split;
513 if (p_fmt->audio.i_channels > 2)
515 msg_Err( obj, "Multistream opus not supported in RTP"
516 " (having %d channels input)",
517 p_fmt->audio.i_channels );
520 rtp_fmt->ptname = "opus";
521 rtp_fmt->pf_packetize = rtp_packetize_simple;
522 rtp_fmt->clock_rate = 48000;
523 rtp_fmt->channels = 2;
524 if (p_fmt->audio.i_channels == 2)
525 rtp_fmt->fmtp = strdup( "sprop-stereo=1" );
528 rtp_fmt->ptname = "VP8";
529 rtp_fmt->pf_packetize = rtp_packetize_vp8;
532 rtp_fmt->ptname = "RAW";
533 rtp_fmt->pf_packetize = rtp_packetize_r420;
534 if( asprintf( &rtp_fmt->fmtp,
535 "sampling=YCbCr-4:2:0; width=%d; height=%d; "
536 "depth=8; colorimetry=BT%s",
537 p_fmt->video.i_visible_width, p_fmt->video.i_visible_height,
538 p_fmt->video.i_visible_height > 576 ? "709-2" : "601-5") == -1 )
540 rtp_fmt->fmtp = NULL;
544 case VLC_CODEC_RGB24:
545 rtp_fmt->ptname = "RAW";
546 rtp_fmt->pf_packetize = rtp_packetize_rgb24;
547 if( asprintf( &rtp_fmt->fmtp,
548 "sampling=RGB; width=%d; height=%d; "
549 "depth=8; colorimetry=SMPTE240M",
550 p_fmt->video.i_visible_width,
551 p_fmt->video.i_visible_height ) == -1 )
553 rtp_fmt->fmtp = NULL;
559 rtp_fmt->ptname = "JPEG";
560 rtp_fmt->payload_type = 26;
561 rtp_fmt->pf_packetize = rtp_packetize_jpeg;
565 msg_Err( obj, "cannot add this stream (unsupported "
566 "codec: %4.4s)", (char*)&p_fmt->i_codec );
575 rtp_packetize_h264_nal( sout_stream_id_sys_t *id,
576 const uint8_t *p_data, int i_data, int64_t i_pts,
577 int64_t i_dts, bool b_last, int64_t i_length );
579 int rtp_packetize_xiph_config( sout_stream_id_sys_t *id, const char *fmtp,
585 /* extract base64 configuration from fmtp */
586 char *start = strstr(fmtp, "configuration=");
587 assert(start != NULL);
588 start += sizeof("configuration=") - 1;
589 char *end = strchr(start, ';');
591 size_t len = end - start;
593 char *b64 = malloc(len + 1);
597 memcpy(b64, start, len);
600 int i_max = rtp_mtu (id) - 6; /* payload max in one packet */
602 uint8_t *p_orig, *p_data;
605 i_data = vlc_b64_decode_binary(&p_orig, b64);
615 int i_count = ( i_data + i_max - 1 ) / i_max;
617 for( int i = 0; i < i_count; i++ )
619 int i_payload = __MIN( i_max, i_data );
620 block_t *out = block_Alloc( 18 + i_payload );
622 unsigned fragtype, numpkts;
633 else if (i == i_count - 1)
638 /* Ident:24, Fragment type:2, Vorbis/Theora Data Type:2, # of pkts:4 */
639 uint32_t header = ((XIPH_IDENT & 0xffffff) << 8) |
640 (fragtype << 6) | (1 << 4) | numpkts;
642 /* rtp common header */
643 rtp_packetize_common( id, out, 0, i_pts );
645 SetDWBE( out->p_buffer + 12, header);
646 SetWBE( out->p_buffer + 16, i_payload);
647 memcpy( &out->p_buffer[18], p_data, i_payload );
651 rtp_packetize_send( id, out );
663 static int rtp_packetize_xiph( sout_stream_id_sys_t *id, block_t *in )
665 int i_max = rtp_mtu (id) - 6; /* payload max in one packet */
666 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
668 uint8_t *p_data = in->p_buffer;
669 int i_data = in->i_buffer;
671 for( int i = 0; i < i_count; i++ )
673 int i_payload = __MIN( i_max, i_data );
674 block_t *out = block_Alloc( 18 + i_payload );
676 unsigned fragtype, numpkts;
679 /* No fragmentation */
689 else if (i == i_count - 1)
694 /* Ident:24, Fragment type:2, Vorbis/Theora Data Type:2, # of pkts:4 */
695 uint32_t header = ((XIPH_IDENT & 0xffffff) << 8) |
696 (fragtype << 6) | (0 << 4) | numpkts;
698 /* rtp common header */
699 rtp_packetize_common( id, out, 0, in->i_pts);
701 SetDWBE( out->p_buffer + 12, header);
702 SetWBE( out->p_buffer + 16, i_payload);
703 memcpy( &out->p_buffer[18], p_data, 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_mpa( 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;
727 for( i = 0; i < i_count; i++ )
729 int i_payload = __MIN( i_max, i_data );
730 block_t *out = block_Alloc( 16 + i_payload );
732 /* rtp common header */
733 rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
735 SetWBE( out->p_buffer + 12, 0 );
736 /* fragment offset in the current frame */
737 SetWBE( out->p_buffer + 14, i * i_max );
738 memcpy( &out->p_buffer[16], p_data, i_payload );
740 out->i_dts = in->i_dts + i * in->i_length / i_count;
741 out->i_length = in->i_length / i_count;
743 rtp_packetize_send( id, out );
754 static int rtp_packetize_mpv( sout_stream_id_sys_t *id, block_t *in )
756 int i_max = rtp_mtu (id) - 4; /* payload max in one packet */
757 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
759 uint8_t *p_data = in->p_buffer;
760 int i_data = in->i_buffer;
762 int b_sequence_start = 0;
763 int i_temporal_ref = 0;
764 int i_picture_coding_type = 0;
765 int i_fbv = 0, i_bfc = 0, i_ffv = 0, i_ffc = 0;
766 int b_start_slice = 0;
768 /* preparse this packet to get some info */
769 if( in->i_buffer > 4 )
772 int i_rest = in->i_buffer;
777 ( p[0] != 0x00 || p[1] != 0x00 || p[2] != 0x01 ) )
791 /* sequence start code */
792 b_sequence_start = 1;
794 else if( *p == 0x00 && i_rest >= 4 )
797 i_temporal_ref = ( p[1] << 2) |((p[2]>>6)&0x03);
798 i_picture_coding_type = (p[2] >> 3)&0x07;
800 if( i_rest >= 4 && ( i_picture_coding_type == 2 ||
801 i_picture_coding_type == 3 ) )
803 i_ffv = (p[3] >> 2)&0x01;
804 i_ffc = ((p[3]&0x03) << 1)|((p[4]>>7)&0x01);
805 if( i_rest > 4 && i_picture_coding_type == 3 )
807 i_fbv = (p[4]>>6)&0x01;
808 i_bfc = (p[4]>>3)&0x07;
812 else if( *p <= 0xaf )
819 for( i = 0; i < i_count; i++ )
821 int i_payload = __MIN( i_max, i_data );
822 block_t *out = block_Alloc( 16 + i_payload );
823 /* 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 */
824 uint32_t h = ( i_temporal_ref << 16 )|
825 ( b_sequence_start << 13 )|
826 ( b_start_slice << 12 )|
827 ( i == i_count - 1 ? 1 << 11 : 0 )|
828 ( i_picture_coding_type << 8 )|
829 ( i_fbv << 7 )|( i_bfc << 4 )|( i_ffv << 3 )|i_ffc;
831 /* rtp common header */
832 rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
833 in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts );
835 SetDWBE( out->p_buffer + 12, h );
837 memcpy( &out->p_buffer[16], p_data, i_payload );
839 out->i_dts = in->i_dts + i * in->i_length / i_count;
840 out->i_length = in->i_length / i_count;
842 rtp_packetize_send( id, out );
852 static int rtp_packetize_ac3( sout_stream_id_sys_t *id, block_t *in )
854 int i_max = rtp_mtu (id) - 2; /* 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( 14 + i_payload );
866 /* rtp common header */
867 rtp_packetize_common( id, out, (i == i_count - 1)?1:0, in->i_pts );
869 out->p_buffer[12] = 1;
871 out->p_buffer[13] = 0x00;
873 memcpy( &out->p_buffer[14], p_data, i_payload );
875 out->i_dts = in->i_dts + i * in->i_length / i_count;
876 out->i_length = in->i_length / i_count;
878 rtp_packetize_send( id, out );
888 static int rtp_packetize_simple(sout_stream_id_sys_t *id, block_t *block)
890 bool marker = (block->i_flags & BLOCK_FLAG_DISCONTINUITY) != 0;
892 block = block_Realloc(block, 12, block->i_buffer);
893 if (unlikely(block == NULL))
896 rtp_packetize_common(id, block, marker, block->i_pts);
897 rtp_packetize_send(id, block);
901 static int rtp_packetize_split( sout_stream_id_sys_t *id, block_t *in )
903 int i_max = rtp_mtu (id); /* payload max in one packet */
904 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
906 uint8_t *p_data = in->p_buffer;
907 int i_data = in->i_buffer;
910 for( i = 0; i < i_count; i++ )
912 int i_payload = __MIN( i_max, i_data );
913 block_t *out = block_Alloc( 12 + i_payload );
915 /* rtp common header */
916 rtp_packetize_common( id, out, (i == i_count - 1),
917 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
918 memcpy( &out->p_buffer[12], p_data, i_payload );
920 out->i_dts = in->i_dts + i * in->i_length / i_count;
921 out->i_length = in->i_length / i_count;
923 rtp_packetize_send( id, out );
933 static int rtp_packetize_pcm(sout_stream_id_sys_t *id, block_t *in)
935 unsigned max = rtp_mtu(id);
937 while (in->i_buffer > max)
939 unsigned duration = (in->i_length * max) / in->i_buffer;
940 bool marker = (in->i_flags & BLOCK_FLAG_DISCONTINUITY) != 0;
942 block_t *out = block_Alloc(12 + max);
943 if (unlikely(out == NULL))
949 rtp_packetize_common(id, out, marker, in->i_pts);
950 memcpy(out->p_buffer + 12, in->p_buffer, max);
951 rtp_packetize_send(id, out);
955 in->i_pts += duration;
956 in->i_length -= duration;
957 in->i_flags &= ~BLOCK_FLAG_DISCONTINUITY;
960 return rtp_packetize_simple(id, in); /* zero copy for the last frame */
963 /* split and convert from little endian to network byte order */
964 static int rtp_packetize_swab(sout_stream_id_sys_t *id, block_t *in)
966 unsigned max = rtp_mtu(id);
968 while (in->i_buffer > 0)
970 unsigned payload = (max < in->i_buffer) ? max : in->i_buffer;
971 unsigned duration = (in->i_length * payload) / in->i_buffer;
972 bool marker = (in->i_flags & BLOCK_FLAG_DISCONTINUITY) != 0;
974 block_t *out = block_Alloc(12 + payload);
975 if (unlikely(out == NULL))
981 rtp_packetize_common(id, out, marker, in->i_pts);
982 swab(in->p_buffer, out->p_buffer + 12, payload);
983 rtp_packetize_send(id, out);
985 in->p_buffer += payload;
986 in->i_buffer -= payload;
987 in->i_pts += duration;
988 in->i_length -= duration;
989 in->i_flags &= ~BLOCK_FLAG_DISCONTINUITY;
997 static int rtp_packetize_mp4a_latm( sout_stream_id_sys_t *id, block_t *in )
999 int i_max = rtp_mtu (id) - 2; /* payload max in one packet */
1000 int latmhdrsize = in->i_buffer / 0xff + 1;
1001 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1003 uint8_t *p_data = in->p_buffer, *p_header = NULL;
1004 int i_data = in->i_buffer;
1007 for( i = 0; i < i_count; i++ )
1009 int i_payload = __MIN( i_max, i_data );
1014 out = block_Alloc( 12 + latmhdrsize + i_payload );
1016 /* rtp common header */
1017 rtp_packetize_common( id, out, ((i == i_count - 1) ? 1 : 0),
1018 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
1022 int tmp = in->i_buffer;
1024 p_header=out->p_buffer+12;
1034 memcpy( &out->p_buffer[12+latmhdrsize], p_data, i_payload );
1036 out->i_dts = in->i_dts + i * in->i_length / i_count;
1037 out->i_length = in->i_length / i_count;
1039 rtp_packetize_send( id, out );
1041 p_data += i_payload;
1042 i_data -= i_payload;
1049 static int rtp_packetize_mp4a( sout_stream_id_sys_t *id, block_t *in )
1051 int i_max = rtp_mtu (id) - 4; /* payload max in one packet */
1052 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1054 uint8_t *p_data = in->p_buffer;
1055 int i_data = in->i_buffer;
1058 for( i = 0; i < i_count; i++ )
1060 int i_payload = __MIN( i_max, i_data );
1061 block_t *out = block_Alloc( 16 + i_payload );
1063 /* rtp common header */
1064 rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
1065 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
1067 /* AU headers length (bits) */
1068 out->p_buffer[12] = 0;
1069 out->p_buffer[13] = 2*8;
1070 /* for each AU length 13 bits + idx 3bits, */
1071 SetWBE( out->p_buffer + 14, (in->i_buffer << 3) | 0 );
1073 memcpy( &out->p_buffer[16], p_data, i_payload );
1075 out->i_dts = in->i_dts + i * in->i_length / i_count;
1076 out->i_length = in->i_length / i_count;
1078 rtp_packetize_send( id, out );
1080 p_data += i_payload;
1081 i_data -= i_payload;
1090 #define RTP_H263_HEADER_SIZE (2) // plen = 0
1091 #define RTP_H263_PAYLOAD_START (14) // plen = 0
1092 static int rtp_packetize_h263( sout_stream_id_sys_t *id, block_t *in )
1094 uint8_t *p_data = in->p_buffer;
1095 int i_data = in->i_buffer;
1097 int i_max = rtp_mtu (id) - RTP_H263_HEADER_SIZE; /* payload max in one packet */
1100 int b_v_bit = 0; // no pesky error resilience
1101 int i_plen = 0; // normally plen=0 for PSC packet
1102 int i_pebit = 0; // because plen=0
1108 return VLC_EGENERIC;
1110 if( p_data[0] || p_data[1] )
1113 return VLC_EGENERIC;
1115 /* remove 2 leading 0 bytes */
1118 i_count = ( i_data + i_max - 1 ) / i_max;
1120 for( i = 0; i < i_count; i++ )
1122 int i_payload = __MIN( i_max, i_data );
1123 block_t *out = block_Alloc( RTP_H263_PAYLOAD_START + i_payload );
1124 b_p_bit = (i == 0) ? 1 : 0;
1125 h = ( b_p_bit << 10 )|
1130 /* rtp common header */
1131 //b_m_bit = 1; // always contains end of frame
1132 rtp_packetize_common( id, out, (i == i_count - 1)?1:0,
1133 in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts );
1136 SetWBE( out->p_buffer + 12, h );
1137 memcpy( &out->p_buffer[RTP_H263_PAYLOAD_START], p_data, i_payload );
1139 out->i_dts = in->i_dts + i * in->i_length / i_count;
1140 out->i_length = in->i_length / i_count;
1142 rtp_packetize_send( id, out );
1144 p_data += i_payload;
1145 i_data -= i_payload;
1154 rtp_packetize_h264_nal( sout_stream_id_sys_t *id,
1155 const uint8_t *p_data, int i_data, int64_t i_pts,
1156 int64_t i_dts, bool b_last, int64_t i_length )
1158 const int i_max = rtp_mtu (id); /* payload max in one packet */
1165 i_nal_hdr = p_data[3];
1166 i_nal_type = i_nal_hdr&0x1f;
1168 /* Skip start code */
1173 if( i_data <= i_max )
1175 /* Single NAL unit packet */
1176 block_t *out = block_Alloc( 12 + i_data );
1178 out->i_length = i_length;
1181 rtp_packetize_common( id, out, b_last, i_pts );
1183 memcpy( &out->p_buffer[12], p_data, i_data );
1185 rtp_packetize_send( id, out );
1189 /* FU-A Fragmentation Unit without interleaving */
1190 const int i_count = ( i_data-1 + i_max-2 - 1 ) / (i_max-2);
1196 for( i = 0; i < i_count; i++ )
1198 const int i_payload = __MIN( i_data, i_max-2 );
1199 block_t *out = block_Alloc( 12 + 2 + i_payload );
1200 out->i_dts = i_dts + i * i_length / i_count;
1201 out->i_length = i_length / i_count;
1204 rtp_packetize_common( id, out, (b_last && i_payload == i_data),
1207 out->p_buffer[12] = 0x00 | (i_nal_hdr & 0x60) | 28;
1209 out->p_buffer[13] = ( i == 0 ? 0x80 : 0x00 ) | ( (i == i_count-1) ? 0x40 : 0x00 ) | i_nal_type;
1210 memcpy( &out->p_buffer[14], p_data, i_payload );
1212 rtp_packetize_send( id, out );
1214 i_data -= i_payload;
1215 p_data += i_payload;
1221 static int rtp_packetize_h264( sout_stream_id_sys_t *id, block_t *in )
1223 const uint8_t *p_buffer = in->p_buffer;
1224 int i_buffer = in->i_buffer;
1226 while( i_buffer > 4 && ( p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] != 1 ) )
1232 /* Split nal units */
1233 while( i_buffer > 4 )
1236 int i_size = i_buffer;
1237 int i_skip = i_buffer;
1239 /* search nal end */
1240 for( i_offset = 4; i_offset+2 < i_buffer ; i_offset++)
1242 if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && p_buffer[i_offset+2] == 1 )
1244 /* we found another startcode */
1245 i_size = i_offset - ( p_buffer[i_offset-1] == 0 ? 1 : 0);
1250 /* TODO add STAP-A to remove a lot of overhead with small slice/sei/... */
1251 rtp_packetize_h264_nal( id, p_buffer, i_size,
1252 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts), in->i_dts,
1253 (i_size >= i_buffer), in->i_length * i_size / in->i_buffer );
1263 static int rtp_packetize_amr( sout_stream_id_sys_t *id, block_t *in )
1265 int i_max = rtp_mtu (id) - 2; /* payload max in one packet */
1266 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1268 uint8_t *p_data = in->p_buffer;
1269 int i_data = in->i_buffer;
1272 /* Only supports octet-aligned mode */
1273 for( i = 0; i < i_count; i++ )
1275 int i_payload = __MIN( i_max, i_data );
1276 block_t *out = block_Alloc( 14 + i_payload );
1278 /* rtp common header */
1279 rtp_packetize_common( id, out, ((i == i_count - 1)?1:0),
1280 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
1281 /* Payload header */
1282 out->p_buffer[12] = 0xF0; /* CMR */
1283 out->p_buffer[13] = p_data[0]&0x7C; /* ToC */ /* FIXME: frame type */
1285 /* FIXME: are we fed multiple frames ? */
1286 memcpy( &out->p_buffer[14], p_data+1, i_payload-1 );
1288 out->i_buffer--; /* FIXME? */
1289 out->i_dts = in->i_dts + i * in->i_length / i_count;
1290 out->i_length = in->i_length / i_count;
1292 rtp_packetize_send( id, out );
1294 p_data += i_payload;
1295 i_data -= i_payload;
1302 static int rtp_packetize_t140( sout_stream_id_sys_t *id, block_t *in )
1304 const size_t i_max = rtp_mtu (id);
1305 const uint8_t *p_data = in->p_buffer;
1306 size_t i_data = in->i_buffer;
1308 for( unsigned i_packet = 0; i_data > 0; i_packet++ )
1310 size_t i_payload = i_data;
1312 /* Make sure we stop on an UTF-8 character boundary
1313 * (assuming the input is valid UTF-8) */
1314 if( i_data > i_max )
1318 while( ( p_data[i_payload] & 0xC0 ) == 0x80 )
1320 if( i_payload == 0 )
1323 return VLC_SUCCESS; /* fishy input! */
1329 block_t *out = block_Alloc( 12 + i_payload );
1336 rtp_packetize_common( id, out, 0, in->i_pts + i_packet );
1337 memcpy( out->p_buffer + 12, p_data, i_payload );
1339 out->i_dts = in->i_pts;
1342 rtp_packetize_send( id, out );
1344 p_data += i_payload;
1345 i_data -= i_payload;
1353 static int rtp_packetize_spx( sout_stream_id_sys_t *id, block_t *in )
1355 uint8_t *p_buffer = in->p_buffer;
1356 int i_data_size, i_payload_size, i_payload_padding;
1357 i_data_size = i_payload_size = in->i_buffer;
1358 i_payload_padding = 0;
1361 if ( in->i_buffer > rtp_mtu (id) )
1368 RFC for Speex in RTP says that each packet must end on an octet
1369 boundary. So, we check to see if the number of bytes % 4 is zero.
1370 If not, we have to add some padding.
1372 This MAY be overkill since packetization is handled elsewhere and
1373 appears to ensure the octet boundary. However, better safe than
1376 if ( i_payload_size % 4 )
1378 i_payload_padding = 4 - ( i_payload_size % 4 );
1379 i_payload_size += i_payload_padding;
1383 Allocate a new RTP p_output block of the appropriate size.
1384 Allow for 12 extra bytes of RTP header.
1386 p_out = block_Alloc( 12 + i_payload_size );
1388 if ( i_payload_padding )
1391 The padding is required to be a zero followed by all 1s.
1393 char c_first_pad, c_remaining_pad;
1395 c_remaining_pad = 0xFF;
1398 Allow for 12 bytes before the i_data_size because
1399 of the expected RTP header added during
1400 rtp_packetize_common.
1402 p_out->p_buffer[12 + i_data_size] = c_first_pad;
1403 switch (i_payload_padding)
1406 p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad;
1409 p_out->p_buffer[12 + i_data_size + 1] = c_remaining_pad;
1410 p_out->p_buffer[12 + i_data_size + 2] = c_remaining_pad;
1415 /* Add the RTP header to our p_output buffer. */
1416 rtp_packetize_common( id, p_out, 0,
1417 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
1418 /* Copy the Speex payload to the p_output buffer */
1419 memcpy( &p_out->p_buffer[12], p_buffer, i_data_size );
1421 p_out->i_dts = in->i_dts;
1422 p_out->i_length = in->i_length;
1425 /* Queue the buffer for actual transmission. */
1426 rtp_packetize_send( id, p_out );
1430 static int rtp_packetize_g726( sout_stream_id_sys_t *id, block_t *in, int i_pad )
1432 int i_max = (rtp_mtu( id )- 12 + i_pad - 1) & ~i_pad;
1433 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1435 uint8_t *p_data = in->p_buffer;
1436 int i_data = in->i_buffer;
1441 int i_payload = __MIN( i_max, i_data );
1442 block_t *out = block_Alloc( 12 + i_payload );
1444 /* rtp common header */
1445 rtp_packetize_common( id, out, 0,
1446 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
1448 memcpy( &out->p_buffer[12], p_data, i_payload );
1450 out->i_dts = in->i_dts + i_packet++ * in->i_length / i_count;
1451 out->i_length = in->i_length / i_count;
1453 rtp_packetize_send( id, out );
1455 p_data += i_payload;
1456 i_data -= i_payload;
1463 static int rtp_packetize_g726_16( sout_stream_id_sys_t *id, block_t *in )
1465 return rtp_packetize_g726( id, in, 4 );
1468 static int rtp_packetize_g726_24( sout_stream_id_sys_t *id, block_t *in )
1470 return rtp_packetize_g726( id, in, 8 );
1473 static int rtp_packetize_g726_32( sout_stream_id_sys_t *id, block_t *in )
1475 return rtp_packetize_g726( id, in, 2 );
1478 static int rtp_packetize_g726_40( sout_stream_id_sys_t *id, block_t *in )
1480 return rtp_packetize_g726( id, in, 8 );
1483 #define RTP_VP8_HEADER_SIZE 1
1484 #define RTP_VP8_PAYLOAD_START (12 + RTP_VP8_HEADER_SIZE)
1486 static int rtp_packetize_vp8( sout_stream_id_sys_t *id, block_t *in )
1488 int i_max = rtp_mtu (id) - RTP_VP8_HEADER_SIZE;
1489 int i_count = ( in->i_buffer + i_max - 1 ) / i_max;
1491 uint8_t *p_data = in->p_buffer;
1492 int i_data = in->i_buffer;
1497 return VLC_EGENERIC;
1500 for( int i = 0; i < i_count; i++ )
1502 int i_payload = __MIN( i_max, i_data );
1503 block_t *out = block_Alloc( RTP_VP8_PAYLOAD_START + i_payload );
1510 /* VP8 payload header */
1511 /* All frames are marked as reference ones */
1513 out->p_buffer[12] = 0x10; // partition start
1515 out->p_buffer[12] = 0;
1517 /* rtp common header */
1518 rtp_packetize_common( id, out, (i == i_count - 1),
1519 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
1520 memcpy( &out->p_buffer[RTP_VP8_PAYLOAD_START], p_data, i_payload );
1522 out->i_dts = in->i_dts + i * in->i_length / i_count;
1523 out->i_length = in->i_length / i_count;
1525 rtp_packetize_send( id, out );
1527 p_data += i_payload;
1528 i_data -= i_payload;
1536 static int rtp_packetize_rawvideo( sout_stream_id_sys_t *id, block_t *in, vlc_fourcc_t i_format )
1538 int i_width, i_height;
1539 rtp_get_video_geometry( id, &i_width, &i_height );
1540 int i_pgroup; /* Size of a group of pixels */
1541 int i_xdec, i_ydec; /* sub-sampling factor in x and y */
1544 case VLC_CODEC_RGB24:
1546 i_xdec = i_ydec = 1;
1548 case VLC_CODEC_R420:
1550 i_xdec = i_ydec = 2;
1553 vlc_assert_unreachable();
1556 static const int RTP_HEADER_LEN = 12;
1557 /* each partial or complete line needs a 6 byte header */
1558 const int i_line_header_size = 6;
1559 const int i_min_line_size = i_line_header_size + i_pgroup;
1560 uint8_t *p_data = in->p_buffer;
1562 for( uint16_t i_line_number = 0, i_column = 0; i_line_number < i_height; )
1564 /* Allocate a packet */
1565 int i_payload = (int)(rtp_mtu (id) - RTP_HEADER_LEN);
1566 if( i_payload <= 0 )
1568 block_Release( in );
1569 return VLC_EGENERIC;
1572 block_t *out = block_Alloc( RTP_HEADER_LEN + i_payload );
1573 if( unlikely( out == NULL ) )
1575 block_Release( in );
1579 /* Do headers first... */
1581 /* Write extended seqnum */
1582 uint8_t *p_outdata = out->p_buffer + RTP_HEADER_LEN;
1583 SetWBE( p_outdata, rtp_get_extended_sequence( id ) );
1587 uint8_t *p_headers = p_outdata;
1589 for( uint8_t i_cont = 0x80; i_cont && i_payload > i_min_line_size; )
1591 i_payload -= i_line_header_size;
1593 int i_pixels = i_width - i_column;
1594 int i_length = (i_pixels * i_pgroup) / i_xdec;
1596 const bool b_next_line = i_payload >= i_length;
1599 i_pixels = (i_payload / i_pgroup) * i_xdec;
1600 i_length = (i_pixels * i_pgroup) / i_xdec;
1603 i_payload -= i_length;
1606 SetWBE( p_outdata, i_length );
1609 /* write line number */
1610 /* TODO: support interlaced */
1611 const uint8_t i_field = 0;
1612 SetWBE( p_outdata, i_line_number );
1613 *p_outdata |= i_field << 7;
1616 /* continue if there's still room in the packet and we have more lines */
1617 i_cont = (i_payload > i_min_line_size && i_line_number < (i_height - i_ydec)) ? 0x80 : 0x00;
1619 /* write offset and continuation marker */
1620 SetWBE( p_outdata, i_column );
1621 *p_outdata |= i_cont;
1627 i_line_number += i_ydec;
1631 i_column += i_pixels;
1635 /* write the actual video data here */
1636 for( uint8_t i_cont = 0x80; i_cont; p_headers += i_line_header_size )
1638 const uint16_t i_length = GetWBE( p_headers );
1639 const uint16_t i_lin = GetWBE( p_headers + 2 ) & 0x7fff;
1640 uint16_t i_offs = GetWBE( p_headers + 4 ) & 0x7fff;
1641 i_cont = p_headers[4] & 0x80;
1643 if( i_format == VLC_CODEC_RGB24 )
1645 const int i_ystride = i_width * i_pgroup;
1647 memcpy( p_outdata, p_data + (i_lin * i_ystride) + (i_offs * i_pgroup), i_length );
1648 p_outdata += i_length;
1650 else if( i_format == VLC_CODEC_R420 )
1652 memcpy( p_outdata, p_data, i_length );
1653 p_outdata += i_length;
1656 else vlc_assert_unreachable();
1659 /* rtp common header */
1660 rtp_packetize_common( id, out, i_line_number >= i_height,
1661 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
1663 out->i_dts = in->i_dts;
1664 out->i_length = in->i_length;
1666 rtp_packetize_send( id, out );
1669 block_Release( in );
1673 static int rtp_packetize_r420( sout_stream_id_sys_t *id, block_t *in )
1675 return rtp_packetize_rawvideo( id, in, VLC_CODEC_R420 );
1678 static int rtp_packetize_rgb24( sout_stream_id_sys_t *id, block_t *in )
1680 return rtp_packetize_rawvideo( id, in, VLC_CODEC_RGB24 );
1683 static int rtp_packetize_jpeg( sout_stream_id_sys_t *id, block_t *in )
1685 uint8_t *p_data = in->p_buffer;
1686 int i_data = in->i_buffer;
1687 uint8_t *bufend = p_data + i_data;
1689 const uint8_t *qtables = NULL;
1691 int off = 0; // fragment offset in frame
1692 int y_sampling_factor;
1693 // type is set by pixel format (determined by y_sampling_factor):
1696 // += 64 if DRI present
1698 int w = 0; // Width in multiples of 8
1699 int h = 0; // Height in multiples of 8
1700 int restart_interval;
1704 if (GetWBE(p_data) != 0xffd8)
1709 /* parse the header to get necessary info */
1710 int header_finished = 0;
1711 while (!header_finished && p_data + 4 <= bufend) {
1712 uint16_t marker = GetWBE(p_data);
1713 uint8_t *section = p_data + 2;
1714 int section_size = GetWBE(section);
1715 uint8_t *section_body = p_data + 4;
1716 if (section + section_size > bufend)
1719 assert((marker & 0xff00) == 0xff00);
1722 case 0xffdb /*DQT*/:
1723 if (section_body[0])
1724 goto error; // Only 8-bit precision is supported
1726 /* a quantization table is 64 bytes long */
1727 nb_qtables = section_size / 65;
1728 qtables = section_body;
1730 case 0xffc0 /*SOF0*/:
1732 int height = GetWBE(§ion_body[1]);
1733 int width = GetWBE(§ion_body[3]);
1734 if (width > 2040 || height > 2040)
1736 // larger than limit supported by RFC 2435
1739 // Round up by 8, divide by 8
1740 w = ((width+7)&~7) >> 3;
1741 h = ((height+7)&~7) >> 3;
1743 // Get components sampling to determine type
1744 // Y has component ID 1
1745 // Possible configurations of sampling factors:
1746 // Y - 0x22, Cb - 0x11, Cr - 0x11 => yuvj420p
1747 // Y - 0x21, Cb - 0x11, Cr - 0x11 => yuvj422p
1749 // Only 3 components are supported by RFC 2435
1750 if (section_body[5] != 3) // Number of components
1752 for (int j = 0; j < 3; j++)
1754 if (section_body[6 + j * 3] == 1 /* Y */)
1756 y_sampling_factor = section_body[6 + j * 3 + 1];
1758 else if (section_body[6 + j * 3 + 1] != 0x11)
1760 // Sampling factor is unsupported by RFC 2435
1766 case 0xffdd /*DRI*/:
1767 restart_interval = GetWBE(section_body);
1770 case 0xffda /*SOS*/:
1771 /* SOS is last marker in the header */
1772 header_finished = 1;
1775 // Step over marker, 16bit length and section body
1776 p_data += 2 + section_size;
1777 i_data -= 2 + section_size;
1779 if (!header_finished)
1784 switch (y_sampling_factor)
1786 case 0x22: // yuvj420p
1789 case 0x21: // yuvj422p
1793 goto error; // Sampling format unsupported by RFC 2435
1801 int hdr_size = 8 + dri_found * 4;
1802 if (off == 0 && nb_qtables)
1803 hdr_size += 4 + 64 * nb_qtables;
1805 int i_payload = __MIN( i_data, (int)(rtp_mtu (id) - hdr_size) );
1806 if ( i_payload <= 0 )
1809 block_t *out = block_Alloc( 12 + hdr_size + i_payload );
1812 block_Release( in );
1816 uint8_t *p = out->p_buffer + 12;
1817 /* set main header */
1818 /* set type-specific=0, set offset in following 24 bits: */
1819 SetDWBE(p, off & 0x00ffffff);
1822 *p++ = 255; // Quant value
1826 // Write restart_marker_hdr if needed
1829 SetWBE(p, restart_interval);
1831 // restart_count. Hardcoded same value as in gstreamer implementation
1836 if (off == 0 && nb_qtables)
1838 /* set quantization tables header */
1841 SetWBE (p, 64 * nb_qtables);
1843 for (int i = 0; i < nb_qtables; i++)
1845 memcpy (p, &qtables[65 * i + 1], 64);
1850 /* rtp common header */
1851 rtp_packetize_common( id, out, (i_payload == i_data),
1852 (in->i_pts > VLC_TS_INVALID ? in->i_pts : in->i_dts) );
1853 memcpy( p, p_data, i_payload );
1855 out->i_dts = in->i_dts;
1856 out->i_length = in->i_length;
1858 rtp_packetize_send( id, out );
1860 p_data += i_payload;
1861 i_data -= i_payload;
1869 return VLC_EGENERIC;