1 /*****************************************************************************
2 * rtcp.c: RTP/RTCP source file
3 *****************************************************************************
4 * Copyright (C) 2005-2007 M2X
8 * Authors: Jean-Paul Saman <jpsaman #_at_# videolan dot org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
25 #include <netinet/in.h>
32 #include <vlc_common.h>
34 #include <vlc_block.h>
39 void send_RTCP( vlc_object_t *p_this, rtcp_event_t );
40 void rtcp_schedule( vlc_object_t *p_this, mtime_t, rtcp_event_t );
42 /* SDES support functions */
43 static int SDES_client_item_add( rtcp_client_t *p_client, int i_item, char *psz_name )
45 rtcp_SDES_item_t *p_item = NULL;
47 p_item = (rtcp_SDES_item_t *) malloc( sizeof( rtcp_SDES_item_t ) );
50 p_item->u_type = i_item;
51 p_item->psz_data = strdup( psz_name );
52 p_item->i_index = p_client->i_items + 1;;
53 INSERT_ELEM( p_client->pp_sdes, p_client->i_items,
54 p_item->i_index, p_item );
58 static int SDES_client_item_del( rtcp_client_t *p_client )
62 for( i=0; i < p_client->i_items; i++ )
64 rtcp_SDES_item_t *p_old = p_client->pp_sdes[i];
65 REMOVE_ELEM( p_client->pp_sdes, p_client->i_items, i );
68 free( p_old->psz_data );
74 int rtcp_add_client( vlc_object_t *p_this, uint32_t u_ssrc, uint32_t *i_pos )
76 rtcp_t *p_rtcp = (rtcp_t *) p_this;
77 rtcp_client_t *p_client = NULL;
79 vlc_object_lock( p_rtcp );
80 p_client = (rtcp_client_t*) malloc( sizeof(rtcp_client_t) );
83 p_client->i_index = p_rtcp->i_clients + 1;
84 p_client->b_deleted = false;
85 *i_pos = p_client->i_index ;
86 INSERT_ELEM( p_rtcp->pp_clients, p_rtcp->i_clients,
87 p_client->i_index, p_client );
90 vlc_object_unlock( p_rtcp );
94 int rtcp_del_client( vlc_object_t *p_this, uint32_t u_ssrc )
96 rtcp_t *p_rtcp = (rtcp_t *) p_this;
99 vlc_object_lock( p_rtcp );
100 if( p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos ) == VLC_SUCCESS )
102 rtcp_client_t *p_old = p_rtcp->pp_clients[i_pos];
104 p_old->b_deleted = true;
105 p_old->i_timeout = 5 * (p_rtcp->i_date - p_rtcp->i_last_date) +
108 /* BYE message is sent by rtcp_destroy_client() */
110 vlc_object_unlock( p_rtcp );
114 /* rtcp_cleanup_clients should not be called too often */
115 int rtcp_cleanup_clients( vlc_object_t *p_this )
117 rtcp_t *p_rtcp = (rtcp_t *) p_this;
120 vlc_object_lock( p_rtcp );
121 for( i=0; i < p_rtcp->i_clients; i++ )
123 rtcp_client_t *p_old = p_rtcp->pp_clients[i];
125 if( p_old->b_deleted &&
126 (p_old->i_timeout > mdate()) )
128 REMOVE_ELEM( p_rtcp->pp_clients, p_rtcp->i_clients, i );
130 SDES_client_item_del( p_old );
134 vlc_object_unlock( p_rtcp );
138 /* Close communication with clients and release allocated objects */
139 int rtcp_destroy_clients( vlc_object_t *p_this )
141 rtcp_t *p_rtcp = (rtcp_t *) p_this;
144 for( i=0; i < p_rtcp->i_clients; i++ )
146 rtcp_pkt_t *pkt = NULL;
147 rtcp_client_t *p_old = p_rtcp->pp_clients[i];
149 p_rtcp->pf_del_client( p_this, p_old->u_ssrc );
150 pkt = rtcp_pkt_new( p_this, RTCP_BYE );
153 block_t *p_block = NULL;
154 p_block = rtcp_encode_BYE( p_this, pkt, strdup("server is leaving") );
157 * send_RTCP( p_this, p_block );
162 /* wait till all clients have been signalled */
163 while( p_rtcp->i_clients != 0 )
165 p_rtcp->pf_cleanup_clients( p_this );
171 /* rtcp_find_client should be called with the object lock held.
172 * vlc_mutex_lock( &p_rtcp->obj_lock );
174 int rtcp_find_client( vlc_object_t *p_this, uint32_t u_ssrc, uint32_t *i_pos )
176 rtcp_t *p_rtcp = (rtcp_t *) p_this;
179 for( i=0; i < p_rtcp->i_clients; i++ )
181 if( p_rtcp->pp_clients[i]->u_ssrc == u_ssrc )
191 /*--------------------------------------------------------------------------
192 * rtcp_interval - Calculate the interval in seconds for sending RTCP packets.
193 *--------------------------------------------------------------------------
195 uint64_t rtcp_interval( vlc_object_t *p_this, uint64_t u_bandwidth, uint32_t u_ssrc,
196 bool b_sender, bool b_first )
198 rtcp_t *p_rtcp = (rtcp_t *) p_this;
199 rtcp_client_t *p_client = NULL;
200 uint32_t i_rtcp_min = 5; /* seconds */
202 double i_bandwidth = u_bandwidth;
203 const double i_compensation = 2.71828 - 1.5;
204 double i_interval = 0;
205 int n = p_rtcp->i_clients;
208 i_rtcp_min = (i_rtcp_min >> 1);
210 if( (double)(p_rtcp->u_active) <= (double)(p_rtcp->u_clients * 0.25) )
214 i_bandwidth = i_bandwidth * 0.25;
215 n = p_rtcp->u_active;
219 i_bandwidth = i_bandwidth * ( 1 - 0.25 );
220 n = n - p_rtcp->u_active;
223 /* calculate average time between reports */
224 p_client = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
228 i_interval = p_client->p_stats->u_avg_pkt_size * ( n / i_bandwidth );
229 if( i_interval < i_rtcp_min )
230 i_interval = i_rtcp_min;
231 i_interval = i_interval * ( drand48() + 0.5 );
232 i_interval = (double) (i_interval / i_compensation);
234 return (uint64_t)i_interval;
237 /*--------------------------------------------------------------------------
238 * rtcp_expire - decides to sent an RTCP report or a BYE record
239 *--------------------------------------------------------------------------
241 void rtcp_expire( vlc_object_t *p_this, rtcp_event_t rtcp_event, uint64_t u_bandwidth,
242 uint32_t u_ssrc, bool b_sender, bool *b_first )
244 rtcp_t *p_rtcp = (rtcp_t *) p_this;
245 rtcp_client_t *p_client = NULL;
246 rtcp_stats_t *p_stats = NULL;
247 mtime_t i_interval = 0;
250 p_client = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
253 p_stats = (rtcp_stats_t*) p_client->p_stats;
254 i_interval = (mtime_t) rtcp_interval( p_this, u_bandwidth,
255 u_ssrc, b_sender, *b_first );
256 p_rtcp->i_next_date = p_rtcp->i_last_date + i_interval;
261 if( p_rtcp->i_next_date <= p_rtcp->i_date )
262 send_RTCP( p_this, rtcp_event );
264 rtcp_schedule( p_this, p_rtcp->i_next_date, rtcp_event );
268 if( p_rtcp->i_next_date <= p_rtcp->i_date )
270 send_RTCP( p_this, rtcp_event );
272 /* Magic numbers are from RFC 3550 page 92
273 * 1.0/16.0 = 0.0625 and
276 p_stats->u_avg_pkt_size = (uint64_t)
277 ( (double) ( (double)p_stats->u_sent_pkt_size / ((double)0.0625) ) +
278 ( ((double)0.9357) * p_stats->u_avg_pkt_size ) );
281 p_rtcp->i_last_date = p_rtcp->i_date;
282 i_interval = rtcp_interval( p_this, u_bandwidth,
283 u_ssrc, b_sender, *b_first );
284 rtcp_schedule( p_this, p_rtcp->i_next_date + i_interval, rtcp_event );
289 rtcp_schedule( p_this, p_rtcp->i_next_date, rtcp_event );
293 p_rtcp->i_date = p_rtcp->i_next_date;
296 /*--------------------------------------------------------------------------
297 * Local functions prototoypes
298 *--------------------------------------------------------------------------
300 static int rtcp_decode_SR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
301 static int rtcp_decode_RR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
302 static int rtcp_decode_SR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
303 static int rtcp_decode_SDES( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
304 static int rtcp_decode_BYE( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
305 static int rtcp_decode_APP( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
307 /*--------------------------------------------------------------------------
309 *--------------------------------------------------------------------------
311 static int rtcp_decode_SR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
313 rtcp_t *p_rtcp = (rtcp_t *) p_this;
319 msg_Dbg( p_this, "decoding record: SR" );
321 /* parse sender info */
322 p_pkt->u_payload_type = RTCP_SR;
323 p_pkt->report.sr.ntp_timestampH = bs_read( p_rtcp->bs, 32 );
324 p_pkt->report.sr.ntp_timestampL = bs_read( p_rtcp->bs, 32 );
325 p_pkt->report.sr.rtp_timestamp = bs_read( p_rtcp->bs, 32 );
326 p_pkt->report.sr.u_pkt_count = bs_read( p_rtcp->bs, 32 ); /*sender*/
327 p_pkt->report.sr.u_octet_count = bs_read( p_rtcp->bs, 32 ); /*sender*/
329 /* parse report block */
330 for( i=0; i < p_pkt->u_report; i++ )
332 rtcp_client_t *p_client = NULL;
337 u_ssrc = bs_read( p_rtcp->bs, 32 );
339 result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
340 if( result == VLC_EGENERIC )
342 result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
343 if( result == VLC_EGENERIC )
346 vlc_object_lock( p_rtcp );
347 p_client = p_rtcp->pp_clients[i_pos];
349 p_client->p_stats->u_SR_received++;
350 p_client->p_stats->u_pkt_count++;
351 p_client->p_stats->u_octet_count++;
353 msg_Dbg( p_this, "SR received %d, packet count %d, octect count %d, SSRC count %d",
354 p_client->p_stats->u_SR_received,
355 p_client->p_stats->u_pkt_count,
356 p_client->p_stats->u_octet_count,
359 p_client->p_stats->u_fraction_lost = bs_read( p_rtcp->bs, 8 );
360 p_client->p_stats->u_pkt_lost = bs_read( p_rtcp->bs, 24 );
361 p_client->p_stats->u_highest_seq_no = bs_read( p_rtcp->bs, 32 );
362 p_client->p_stats->u_jitter = bs_read( p_rtcp->bs, 32 );
363 p_client->p_stats->u_last_SR = bs_read( p_rtcp->bs, 32 );
364 p_client->p_stats->u_delay_since_last_SR = (mtime_t) bs_read( p_rtcp->bs, 32 );
366 /* Magic numbers are from RFC 3550 page 92
367 * 1.0/16.0 = 0.0625 and
370 p_client->p_stats->u_avg_pkt_size = (uint64_t)
371 ( (double)((double)p_client->p_stats->u_sent_pkt_size * (double)(0.0625)) +
372 ((double)(0.9375) * p_client->p_stats->u_avg_pkt_size) );
374 msg_Dbg( p_this, "fract lost %d, packet lost %d, highest seqno %d, "
375 "jitter %d, last SR %d, delay %lld",
376 p_client->p_stats->u_fraction_lost,
377 p_client->p_stats->u_pkt_lost,
378 p_client->p_stats->u_highest_seq_no,
379 p_client->p_stats->u_jitter,
380 p_client->p_stats->u_last_SR,
381 p_client->p_stats->u_delay_since_last_SR );
383 vlc_object_unlock( p_rtcp );
388 static int rtcp_decode_RR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
390 rtcp_t *p_rtcp = (rtcp_t *) p_this;
396 msg_Dbg( p_this, "decoding record: RR" );
398 for( i=0; i < p_pkt->u_report; i++ )
400 rtcp_client_t *p_client = NULL;
405 u_ssrc = bs_read( p_rtcp->bs, 32 );
407 result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
408 if( result == VLC_EGENERIC )
410 result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
411 if( result == VLC_EGENERIC )
415 vlc_object_lock( p_rtcp );
416 p_client = p_rtcp->pp_clients[i_pos];
418 p_client->p_stats->u_RR_received++;
419 msg_Dbg( p_this, "RR received %d, SSRC %d",
420 p_client->p_stats->u_RR_received, u_ssrc );
422 p_client->p_stats->u_fraction_lost = bs_read( p_rtcp->bs, 8 );
423 p_client->p_stats->u_pkt_lost = bs_read( p_rtcp->bs, 24 );
424 p_client->p_stats->u_highest_seq_no = bs_read( p_rtcp->bs, 32 );
425 p_client->p_stats->u_jitter = bs_read( p_rtcp->bs, 32 );
426 p_client->p_stats->u_last_SR = bs_read( p_rtcp->bs, 32 );
427 p_client->p_stats->u_delay_since_last_SR = (mtime_t) bs_read( p_rtcp->bs, 32 );
429 /* Magic numbers are from RFC 3550 page 92
430 * 1.0/16.0 = 0.0625 and
433 p_client->p_stats->u_avg_pkt_size = (uint64_t)
434 ( (double)((double)p_client->p_stats->u_sent_pkt_size * (double)(0.0625)) +
435 ((double)(0.9375) * p_client->p_stats->u_avg_pkt_size) );
437 msg_Dbg( p_this, "fract lost %d, packet lost %d, highest seqno %d, "
438 "jitter %d, last SR %d, delay %lld",
439 p_client->p_stats->u_fraction_lost,
440 p_client->p_stats->u_pkt_lost,
441 p_client->p_stats->u_highest_seq_no,
442 p_client->p_stats->u_jitter,
443 p_client->p_stats->u_last_SR,
444 p_client->p_stats->u_delay_since_last_SR );
446 vlc_object_unlock( p_rtcp );
451 static int rtcp_decode_SDES( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
453 rtcp_t *p_rtcp = (rtcp_t *) p_this;
459 msg_Dbg( p_this, "decoding record: SDES" );
461 for( i = 0; i < p_pkt->u_report; i++ )
463 rtcp_client_t *p_client = NULL;
467 uint8_t u_length = 0;
471 u_ssrc = bs_read( p_rtcp->bs, 32 );
473 result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
474 if( result == VLC_EGENERIC )
476 result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
477 if( result == VLC_EGENERIC )
481 vlc_object_lock( p_rtcp );
482 p_client = p_rtcp->pp_clients[i_pos];
484 u_item = bs_read( p_rtcp->bs, 8 );
487 case RTCP_SDES_CNAME:
489 case RTCP_SDES_EMAIL:
490 case RTCP_SDES_PHONE:
497 u_length = bs_read( p_rtcp->bs, 8 );
498 for( i = 0 ; i < u_length; i++ )
500 psz_name[i] = bs_read( p_rtcp->bs, 8 );
502 SDES_client_item_add( p_client, u_item, psz_name );
506 case RTCP_SDES_PRIV: /* ignoring these */
508 uint8_t u_prefix_len = 0;
509 uint8_t u_length = 0;
510 char psz_prefix_name[255];
513 u_length = bs_read( p_rtcp->bs, 8 );
514 u_prefix_len = bs_read( p_rtcp->bs, 8 );
515 if( u_prefix_len > 254 )
518 for( i=0 ; i < u_prefix_len; i++ )
520 psz_prefix_name[i] = bs_read( p_rtcp->bs, 8 );
522 psz_prefix_name[255] = '\0';
523 SDES_client_item_add( p_client, u_item, psz_prefix_name );
525 for( i=0 ; i < u_length; i++ )
527 psz_name[i] = bs_read( p_rtcp->bs, 8 );
529 psz_name[255] = '\0';
530 SDES_client_item_add( p_client, u_item, psz_name );
537 /* Magic numbers are from RFC 3550 page 92
538 * 1.0/16.0 = 0.0625 and
541 p_client->p_stats->u_avg_pkt_size = (uint64_t)
542 ( (double)((double)p_client->p_stats->u_sent_pkt_size * (double)(0.0625)) +
543 ((double)(0.9375) * p_client->p_stats->u_avg_pkt_size) );
546 vlc_object_unlock( p_rtcp );
551 static int rtcp_decode_BYE( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
553 rtcp_t *p_rtcp = (rtcp_t *) p_this;
555 uint8_t u_length = 0;
561 msg_Dbg( p_this, "decoding record: BYE" );
563 u_ssrc = bs_read( p_rtcp->bs, 32 );
564 p_rtcp->pf_del_client( p_this, u_ssrc );
565 u_length = p_pkt->u_length-1;
566 for( i = 0 ; i < u_length; i++ )
568 u_ssrc = bs_read( p_rtcp->bs, 8 );
569 p_rtcp->pf_del_client( p_this, u_ssrc );
574 static int rtcp_decode_APP( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
576 rtcp_t *p_rtcp = (rtcp_t *) p_this;
577 rtcp_client_t *p_client = NULL;
579 char* psz_data = NULL;
588 msg_Dbg( p_this, "decoding record: APP" );
590 u_ssrc = bs_read( p_rtcp->bs, 32 );
592 result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
593 if( result == VLC_EGENERIC )
595 result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
596 if( result == VLC_EGENERIC )
600 vlc_object_lock( p_rtcp );
601 p_client = p_rtcp->pp_clients[i_pos];
603 for( i = 0 ; i < 4; i++ )
605 psz_name[i] = bs_read( p_rtcp->bs, 8 );
609 p_pkt->u_payload_type = RTCP_APP;
610 p_pkt->report.app.psz_prefix = strdup( psz_name );
611 p_pkt->report.app.u_prefix_len = 4;
612 p_pkt->u_length -= 4;
614 psz_data = (char *) malloc( p_pkt->u_length );
616 vlc_object_unlock( p_rtcp );
620 for( i = 0; i < p_pkt->u_length; i-- )
622 psz_data[i] = bs_read( p_rtcp->bs, 8 );
624 psz_data[p_pkt->u_length] = '\0';
626 p_pkt->report.app.psz_data = strdup( psz_data );
627 p_pkt->report.app.u_length = p_pkt->u_length;
630 vlc_object_unlock( p_rtcp );
632 /* Just ignore this packet */
636 /* Decode RTCP packet
637 * Decode incoming RTCP packet and inspect the records types.
639 int rtcp_pkt_decode( vlc_object_t *p_this, rtcp_pkt_t *p_pkt, block_t *p_block )
641 rtcp_t *p_rtcp = (rtcp_t *) p_this;
643 if( !p_pkt && !p_block )
646 bs_init( p_rtcp->bs, p_block->p_buffer, p_block->i_buffer );
648 p_pkt->u_version = bs_read( p_rtcp->bs, 2 );
649 p_pkt->b_padding = bs_read( p_rtcp->bs, 1 ) ? true : false;
650 p_pkt->u_report = bs_read( p_rtcp->bs, 5 );
651 p_pkt->u_payload_type = bs_read( p_rtcp->bs, 8 );
652 p_pkt->u_length = bs_read( p_rtcp->bs, 16 );
654 if( p_pkt->u_payload_type != RTCP_SDES )
655 p_pkt->u_ssrc = bs_read( p_rtcp->bs, 32 );
657 msg_Dbg( p_this, "New RTCP packet: version %d, padding %s, count %d, "
658 "type %d, length %d, SSRC %d",
660 p_pkt->b_padding ? "true" : "false",
662 p_pkt->u_payload_type,
666 while( !bs_eof( p_rtcp->bs ) )
670 switch( p_pkt->u_payload_type )
673 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
674 p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
675 rtcp_decode_SR( p_this, p_pkt );
679 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
680 p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
681 rtcp_decode_RR( p_this, p_pkt );
685 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
686 p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
687 rtcp_decode_SDES( p_this, p_pkt );
691 rtcp_decode_BYE( p_this, p_pkt );
693 if( p_rtcp->pf_find_sender( p_this, pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
694 p_rtcp->pf_del_sender( p_this, p_pkt->u_ssrc );
696 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
697 p_rtcp->pf_del_client( p_this, p_pkt->u_ssrc );
699 if( p_rtcp->u_active < p_rtcp->u_members )
701 rtcp_event_t event = EVENT_BYE;
703 p_rtcp->i_next_date = p_rtcp->i_date +
704 (mtime_t) ( (p_rtcp->u_active / p_rtcp->u_members) *
705 (p_rtcp->i_next_date - p_rtcp->i_date) );
706 p_rtcp->i_last_date = p_rtcp->i_date -
708 ( (mtime_t)(p_rtcp->u_active / p_rtcp->u_members) *
709 (p_rtcp->i_date - p_rtcp->i_last_date) );
710 /* schedule for next period */
711 rtcp_schedule( VLC_OBJECT(p_rtcp), p_rtcp->i_next_date, event );
712 p_rtcp->u_members = p_rtcp->u_active;
714 else p_rtcp->u_members++;
718 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
719 p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
720 rtcp_decode_APP( p_this, p_pkt );
731 * Create RTCP records for reporting to server.
733 rtcp_pkt_t *rtcp_pkt_new( vlc_object_t *p_this, int type )
735 rtcp_pkt_t *p_pkt = NULL;
737 p_pkt = (rtcp_pkt_t *) malloc( sizeof( rtcp_pkt_t ) );
741 memset( p_pkt, 0 , sizeof( rtcp_pkt_t ) );
742 p_pkt->u_version = 2;
743 p_pkt->u_payload_type = type;
744 p_pkt->u_length = RTCP_HEADER_LEN;
749 p_pkt->u_length += sizeof(rtcp_SR_t);
752 p_pkt->u_length += sizeof(rtcp_RR_t);
755 p_pkt->u_length += sizeof(rtcp_SDES_t);
756 if( p_pkt->report.sdes.pp_items )
757 p_pkt->u_length += p_pkt->report.sdes.u_items;
760 p_pkt->u_length += sizeof(rtcp_BYE_t);
763 p_pkt->u_length += sizeof(rtcp_APP_t);
772 void rtcp_pkt_del( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
777 switch( p_pkt->u_payload_type )
783 if( p_pkt->report.sdes.pp_items )
787 for( i = 0; i < p_pkt->report.sdes.u_items; i++ )
789 rtcp_SDES_item_t *p_old =
790 p_pkt->report.sdes.pp_items[i];
791 REMOVE_ELEM( p_pkt->report.sdes.pp_items,
792 p_pkt->report.sdes.u_items, i );
793 p_pkt->report.sdes.u_items--;
794 if( p_old->psz_data )
795 free( p_old->psz_data );
803 if( p_pkt->report.app.psz_prefix )
804 free( p_pkt->report.app.psz_prefix );
805 if( p_pkt->report.app.psz_data )
806 free( p_pkt->report.app.psz_data );
809 msg_Err( p_this, "unknown RTCP packet type %d: "
810 "possible leaking of memory.",
811 p_pkt->u_payload_type );
817 block_t *rtcp_encode_SR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
819 rtcp_t *p_rtcp = (rtcp_t *) p_this;
821 bs_t bits, *s = &bits;
822 block_t *p_block = NULL;
823 rtcp_stats_t *p_stats = NULL;
824 rtcp_client_t *p_client = NULL;
828 if( p_pkt->u_payload_type != RTCP_SR )
831 /* FIXME: Maybe this should be a buffer pool instead */
832 p_block = block_New( p_this, p_pkt->u_length );
836 bs_init( s, p_block->p_buffer, p_block->i_buffer );
839 bs_write( s, 2, p_pkt->u_version );
840 bs_write( s, 1, 0 ); /* padding */
841 bs_write( s, 5, p_pkt->u_report );
842 bs_write( s, 8, p_pkt->u_payload_type );
843 bs_write( s, 16, p_pkt->u_length );
844 bs_write( s, 32, p_pkt->u_ssrc );
848 bs_write( s, 32, ((unsigned int)(ntp_time>>32)) ); /* ntp_timestampH */
849 bs_write( s, 32, ((unsigned int)ntp_time) );/* ntp_timestampL */
851 /* FIXME: Make sure to generate a good RTP server timestamp.
852 p_pkt->report.sr.rtp_timestamp = htonl(
853 (unsigned int) ((double)ntp_time.tv_sec +
854 (double)ntp_time.tv_usec/1000000.) * p_mux->rate
855 + session->start_rtptime ); */
856 bs_write( s, 32, p_pkt->report.sr.rtp_timestamp );
857 bs_write( s, 32, p_pkt->report.sr.u_pkt_count );
858 bs_write( s, 32, p_pkt->report.sr.u_octet_count );
861 result = p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos );
862 if( result == VLC_EGENERIC )
864 msg_Err( p_this, "SR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
869 vlc_object_lock( p_rtcp );
870 p_client = p_rtcp->pp_clients[i_pos];
872 p_stats = p_client->p_stats;
874 msg_Err( p_this, "SR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
878 bs_write( s, 32, p_stats->l_dest_SSRC );
879 bs_write( s, 8, p_stats->u_fraction_lost );
880 bs_write( s, 24, p_stats->u_pkt_lost );
881 bs_write( s, 32, p_stats->u_highest_seq_no );
882 bs_write( s, 32, p_stats->u_jitter );
883 bs_write( s, 32, p_stats->u_last_SR );
884 bs_write( s, 32, p_stats->u_delay_since_last_SR );
887 vlc_object_unlock( p_rtcp );
889 /* possible SR extension */
893 block_t *rtcp_encode_RR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
895 rtcp_t *p_rtcp = (rtcp_t *) p_this;
896 bs_t bits, *s = &bits;
897 block_t *p_block = NULL;
898 rtcp_stats_t *p_stats = NULL;
899 rtcp_client_t *p_client = NULL;
903 if( p_pkt->u_payload_type != RTCP_RR )
906 /* FIXME: Maybe this should be a buffer pool instead */
907 p_block = block_New( p_this, p_pkt->u_length );
911 bs_init( s, p_block->p_buffer, p_block->i_buffer );
914 bs_write( s, 2, p_pkt->u_version );
915 bs_write( s, 1, 0 ); /* padding */
916 bs_write( s, 5, p_pkt->u_report );
917 bs_write( s, 8, p_pkt->u_payload_type );
918 bs_write( s, 16, p_pkt->u_length );
919 bs_write( s, 32, p_pkt->u_ssrc );
922 result = p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos );
923 if( result == VLC_EGENERIC )
925 msg_Err( p_this, "RR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
930 vlc_object_lock( p_rtcp );
931 p_client = p_rtcp->pp_clients[i_pos];
933 p_stats = p_client->p_stats;
935 msg_Err( p_this, "RR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
939 bs_write( s, 32, p_stats->l_dest_SSRC );
940 bs_write( s, 8, p_stats->u_fraction_lost );
941 bs_write( s, 24, p_stats->u_pkt_lost );
942 bs_write( s, 32, p_stats->u_highest_seq_no );
943 bs_write( s, 32, p_stats->u_jitter );
944 bs_write( s, 32, p_stats->u_last_RR );
945 bs_write( s, 32, p_stats->u_delay_since_last_RR );
948 vlc_object_unlock( p_rtcp );
950 /* possible RR extension */
954 block_t *rtcp_encode_SDES( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
956 bs_t bits, *s = &bits;
957 block_t *p_block = NULL;
960 if( p_pkt->u_payload_type != RTCP_SDES )
963 /* FIXME: Maybe this should be a buffer pool instead */
964 p_block = block_New( p_this, p_pkt->u_length );
968 bs_init( s, p_block->p_buffer, p_block->i_buffer );
971 bs_write( s, 2, p_pkt->u_version );
972 bs_write( s, 1, 0 ); /* padding */
973 bs_write( s, 5, p_pkt->u_report ); /* Number of SSRC/CSRC chunks */
974 bs_write( s, 8, p_pkt->u_payload_type );
975 bs_write( s, 16, p_pkt->u_length );
976 bs_write( s, 32, p_pkt->u_ssrc );
979 for( i_chunks = 0; i_chunks < p_pkt->u_report; i_chunks++ )
983 for( i_item = 0 ; i_item < p_pkt->report.sdes.u_items; i_item++ )
985 uint32_t i_count = strlen( p_pkt->report.sdes.pp_items[i_item]->psz_data );
986 uint8_t u_octet = i_count / 8; /* Octect count ??*/
987 rtcp_SDES_item_t *p_item = p_pkt->report.sdes.pp_items[i_item];
988 uint32_t i_pos, i_pad, i_padding;
990 bs_write( s, 8, p_item->u_type );
991 bs_write( s, 8, u_octet );
993 for( i_pos = 0; i_pos < i_count; i_pos++ )
995 /* FIXME: must be UTF 8 encoded */
996 bs_write( s, 8, p_item->psz_data[i_pos] );
999 /* do we need padding to 32 bit boundary? */
1001 if( ((i_count + 2) % 4) != 0 )
1002 i_padding = (i_count + 2) - (((i_count + 2) % 4) << 2);
1003 for( i_pad = 0; i_pad < i_padding; i_pad++ )
1005 bs_write( s, 8, 0 );
1012 block_t *rtcp_encode_BYE( vlc_object_t *p_this, rtcp_pkt_t *p_pkt, char *psz_reason )
1014 bs_t bits, *s = &bits;
1015 block_t *p_block = NULL;
1016 uint32_t i_count = strlen( psz_reason );
1017 uint8_t u_octet = i_count / 8; /* Octect count ??*/
1018 int32_t i_pos, i_pad, i_padding;
1020 if( p_pkt->u_payload_type != RTCP_BYE )
1023 /* FIXME: Maybe this should be a buffer pool instead */
1024 p_block = block_New( p_this, p_pkt->u_length );
1028 bs_init( s, p_block->p_buffer, p_block->i_buffer );
1030 /* Fill in header */
1031 bs_write( s, 2, p_pkt->u_version );
1032 bs_write( s, 1, 0 ); /* padding */
1033 bs_write( s, 5, p_pkt->u_report ); /* Number of SSRC/CSRC chunks */
1034 bs_write( s, 8, p_pkt->u_payload_type );
1035 bs_write( s, 16, p_pkt->u_length );
1036 bs_write( s, 32, p_pkt->u_ssrc );
1038 /* Give reason for leaving */
1039 //FIXME: bs_write( s, 8, p_item->u_type );
1040 bs_write( s, 8, u_octet );
1042 for( i_pos = 0; i_pos < i_count; i_pos++ )
1044 /* FIXME: must be UTF 8 encoded */
1045 bs_write( s, 8, psz_reason[i_pos] );
1048 /* do we need padding to 32 bit boundary? */
1050 if( ((i_count + 2) % 4) != 0 )
1051 i_padding = (i_count + 2) - (((i_count + 2) % 4) << 2);
1052 for( i_pad = 0; i_pad < i_padding; i_pad++ )
1054 bs_write( s, 8, 0 );