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>
30 #include <vlc_block.h>
35 void send_RTCP( vlc_object_t *p_this, rtcp_event_t );
36 void rtcp_schedule( vlc_object_t *p_this, mtime_t, rtcp_event_t );
38 /* SDES support functions */
39 static int SDES_client_item_add( rtcp_client_t *p_client, int i_item, char *psz_name )
41 rtcp_SDES_item_t *p_item = NULL;
43 p_item = (rtcp_SDES_item_t *) malloc( sizeof( rtcp_SDES_item_t ) );
46 p_item->u_type = i_item;
47 p_item->psz_data = strdup( psz_name );
48 p_item->i_index = p_client->i_items + 1;;
49 INSERT_ELEM( p_client->pp_sdes, p_client->i_items,
50 p_item->i_index, p_item );
54 static int SDES_client_item_del( rtcp_client_t *p_client )
58 for( i=0; i < p_client->i_items; i++ )
60 rtcp_SDES_item_t *p_old = p_client->pp_sdes[i];
61 REMOVE_ELEM( p_client->pp_sdes, p_client->i_items, i );
64 free( p_old->psz_data );
70 int rtcp_add_client( vlc_object_t *p_this, uint32_t u_ssrc, uint32_t *i_pos )
72 rtcp_t *p_rtcp = (rtcp_t *) p_this;
73 rtcp_client_t *p_client = NULL;
75 vlc_mutex_lock( &p_rtcp->object_lock );
76 p_client = (rtcp_client_t*) malloc( sizeof(rtcp_client_t) );
79 p_client->i_index = p_rtcp->i_clients + 1;
80 p_client->b_deleted = VLC_FALSE;
81 *i_pos = p_client->i_index ;
82 INSERT_ELEM( p_rtcp->pp_clients, p_rtcp->i_clients,
83 p_client->i_index, p_client );
86 vlc_mutex_unlock( &p_rtcp->object_lock );
90 int rtcp_del_client( vlc_object_t *p_this, uint32_t u_ssrc )
92 rtcp_t *p_rtcp = (rtcp_t *) p_this;
95 vlc_mutex_lock( &p_rtcp->object_lock );
96 if( p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos ) == VLC_SUCCESS )
98 rtcp_client_t *p_old = p_rtcp->pp_clients[i_pos];
100 p_old->b_deleted = VLC_TRUE;
101 p_old->i_timeout = 5 * (p_rtcp->i_date - p_rtcp->i_last_date) +
104 /* BYE message is sent by rtcp_destroy_client() */
106 vlc_mutex_unlock( &p_rtcp->object_lock );
110 /* rtcp_cleanup_clients should not be called too often */
111 int rtcp_cleanup_clients( vlc_object_t *p_this )
113 rtcp_t *p_rtcp = (rtcp_t *) p_this;
116 vlc_mutex_lock( &p_rtcp->object_lock );
117 for( i=0; i < p_rtcp->i_clients; i++ )
119 rtcp_client_t *p_old = p_rtcp->pp_clients[i];
121 if( p_old->b_deleted &&
122 (p_old->i_timeout > mdate()) )
124 REMOVE_ELEM( p_rtcp->pp_clients, p_rtcp->i_clients, i );
126 SDES_client_item_del( p_old );
130 vlc_mutex_unlock( &p_rtcp->object_lock );
134 /* Close communication with clients and release allocated objects */
135 int rtcp_destroy_clients( vlc_object_t *p_this )
137 rtcp_t *p_rtcp = (rtcp_t *) p_this;
140 for( i=0; i < p_rtcp->i_clients; i++ )
142 rtcp_pkt_t *pkt = NULL;
143 rtcp_client_t *p_old = p_rtcp->pp_clients[i];
145 p_rtcp->pf_del_client( p_this, p_old->u_ssrc );
146 pkt = rtcp_pkt_new( p_this, RTCP_BYE );
149 block_t *p_block = NULL;
150 p_block = rtcp_encode_BYE( p_this, pkt, strdup("server is leaving") );
153 * send_RTCP( p_this, p_block );
158 /* wait till all clients have been signalled */
159 while( p_rtcp->i_clients != 0 )
161 p_rtcp->pf_cleanup_clients( p_this );
167 /* rtcp_find_client should be called with the object lock held.
168 * vlc_mutex_lock( &p_rtcp->obj_lock );
170 int rtcp_find_client( vlc_object_t *p_this, uint32_t u_ssrc, uint32_t *i_pos )
172 rtcp_t *p_rtcp = (rtcp_t *) p_this;
175 for( i=0; i < p_rtcp->i_clients; i++ )
177 if( p_rtcp->pp_clients[i]->u_ssrc == u_ssrc )
187 /*--------------------------------------------------------------------------
188 * rtcp_interval - Calculate the interval in seconds for sending RTCP packets.
189 *--------------------------------------------------------------------------
191 uint64_t rtcp_interval( vlc_object_t *p_this, uint64_t u_bandwidth, uint32_t u_ssrc,
192 vlc_bool_t b_sender, vlc_bool_t b_first )
194 rtcp_t *p_rtcp = (rtcp_t *) p_this;
195 rtcp_client_t *p_client = NULL;
196 uint32_t i_rtcp_min = 5; /* seconds */
198 double i_bandwidth = u_bandwidth;
199 const double i_compensation = 2.71828 - 1.5;
200 double i_interval = 0;
201 int n = p_rtcp->i_clients;
204 i_rtcp_min = (i_rtcp_min >> 1);
206 if( (double)(p_rtcp->u_active) <= (double)(p_rtcp->u_clients * 0.25) )
210 i_bandwidth = i_bandwidth * 0.25;
211 n = p_rtcp->u_active;
215 i_bandwidth = i_bandwidth * ( 1 - 0.25 );
216 n = n - p_rtcp->u_active;
219 /* calculate average time between reports */
220 p_client = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
224 i_interval = p_client->p_stats->u_avg_pkt_size * ( n / i_bandwidth );
225 if( i_interval < i_rtcp_min )
226 i_interval = i_rtcp_min;
227 i_interval = i_interval * ( drand48() + 0.5 );
228 i_interval = (double) (i_interval / i_compensation);
230 return (uint64_t)i_interval;
233 /*--------------------------------------------------------------------------
234 * rtcp_expire - decides to sent an RTCP report or a BYE record
235 *--------------------------------------------------------------------------
237 void rtcp_expire( vlc_object_t *p_this, rtcp_event_t rtcp_event, uint64_t u_bandwidth,
238 uint32_t u_ssrc, vlc_bool_t b_sender, vlc_bool_t *b_first )
240 rtcp_t *p_rtcp = (rtcp_t *) p_this;
241 rtcp_client_t *p_client = NULL;
242 rtcp_stats_t *p_stats = NULL;
243 mtime_t i_interval = 0;
246 p_client = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
249 p_stats = (rtcp_stats_t*) p_client->p_stats;
250 i_interval = (mtime_t) rtcp_interval( p_this, u_bandwidth,
251 u_ssrc, b_sender, *b_first );
252 p_rtcp->i_next_date = p_rtcp->i_last_date + i_interval;
257 if( p_rtcp->i_next_date <= p_rtcp->i_date )
258 send_RTCP( p_this, rtcp_event );
260 rtcp_schedule( p_this, p_rtcp->i_next_date, rtcp_event );
264 if( p_rtcp->i_next_date <= p_rtcp->i_date )
266 send_RTCP( p_this, rtcp_event );
268 /* Magic numbers are from RFC 3550 page 92
269 * 1.0/16.0 = 0.0625 and
272 p_stats->u_avg_pkt_size = (uint64_t)
273 ( (double) ( (double)p_stats->u_sent_pkt_size / ((double)0.0625) ) +
274 ( ((double)0.9357) * p_stats->u_avg_pkt_size ) );
277 p_rtcp->i_last_date = p_rtcp->i_date;
278 i_interval = rtcp_interval( p_this, u_bandwidth,
279 u_ssrc, b_sender, *b_first );
280 rtcp_schedule( p_this, p_rtcp->i_next_date + i_interval, rtcp_event );
281 *b_first = VLC_FALSE;
285 rtcp_schedule( p_this, p_rtcp->i_next_date, rtcp_event );
289 p_rtcp->i_date = p_rtcp->i_next_date;
292 /*--------------------------------------------------------------------------
293 * Local functions prototoypes
294 *--------------------------------------------------------------------------
296 static int rtcp_decode_SR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
297 static int rtcp_decode_RR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
298 static int rtcp_decode_SR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
299 static int rtcp_decode_SDES( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
300 static int rtcp_decode_BYE( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
301 static int rtcp_decode_APP( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
303 /*--------------------------------------------------------------------------
305 *--------------------------------------------------------------------------
307 static int rtcp_decode_SR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
309 rtcp_t *p_rtcp = (rtcp_t *) p_this;
315 msg_Dbg( p_this, "decoding record: SR" );
317 /* parse sender info */
318 p_pkt->u_payload_type = RTCP_SR;
319 p_pkt->report.sr.ntp_timestampH = bs_read( p_rtcp->bs, 32 );
320 p_pkt->report.sr.ntp_timestampL = bs_read( p_rtcp->bs, 32 );
321 p_pkt->report.sr.rtp_timestamp = bs_read( p_rtcp->bs, 32 );
322 p_pkt->report.sr.u_pkt_count = bs_read( p_rtcp->bs, 32 ); /*sender*/
323 p_pkt->report.sr.u_octet_count = bs_read( p_rtcp->bs, 32 ); /*sender*/
325 /* parse report block */
326 for( i=0; i < p_pkt->u_report; i++ )
328 rtcp_client_t *p_client = NULL;
333 u_ssrc = bs_read( p_rtcp->bs, 32 );
335 result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
336 if( result == VLC_EGENERIC )
338 result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
339 if( result == VLC_EGENERIC )
342 vlc_mutex_lock( &p_rtcp->object_lock );
343 p_client = p_rtcp->pp_clients[i_pos];
345 p_client->p_stats->u_SR_received++;
346 p_client->p_stats->u_pkt_count++;
347 p_client->p_stats->u_octet_count++;
349 msg_Dbg( p_this, "SR received %d, packet count %d, octect count %d, SSRC count %d",
350 p_client->p_stats->u_SR_received,
351 p_client->p_stats->u_pkt_count,
352 p_client->p_stats->u_octet_count,
355 p_client->p_stats->u_fraction_lost = bs_read( p_rtcp->bs, 8 );
356 p_client->p_stats->u_pkt_lost = bs_read( p_rtcp->bs, 24 );
357 p_client->p_stats->u_highest_seq_no = bs_read( p_rtcp->bs, 32 );
358 p_client->p_stats->u_jitter = bs_read( p_rtcp->bs, 32 );
359 p_client->p_stats->u_last_SR = bs_read( p_rtcp->bs, 32 );
360 p_client->p_stats->u_delay_since_last_SR = (mtime_t) bs_read( p_rtcp->bs, 32 );
362 /* Magic numbers are from RFC 3550 page 92
363 * 1.0/16.0 = 0.0625 and
366 p_client->p_stats->u_avg_pkt_size = (uint64_t)
367 ( (double)((double)p_client->p_stats->u_sent_pkt_size * (double)(0.0625)) +
368 ((double)(0.9375) * p_client->p_stats->u_avg_pkt_size) );
370 msg_Dbg( p_this, "fract lost %d, packet lost %d, highest seqno %d, "
371 "jitter %d, last SR %d, delay %lld",
372 p_client->p_stats->u_fraction_lost,
373 p_client->p_stats->u_pkt_lost,
374 p_client->p_stats->u_highest_seq_no,
375 p_client->p_stats->u_jitter,
376 p_client->p_stats->u_last_SR,
377 p_client->p_stats->u_delay_since_last_SR );
379 vlc_mutex_unlock( &p_rtcp->object_lock );
384 static int rtcp_decode_RR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
386 rtcp_t *p_rtcp = (rtcp_t *) p_this;
392 msg_Dbg( p_this, "decoding record: RR" );
394 for( i=0; i < p_pkt->u_report; i++ )
396 rtcp_client_t *p_client = NULL;
401 u_ssrc = bs_read( p_rtcp->bs, 32 );
403 result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
404 if( result == VLC_EGENERIC )
406 result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
407 if( result == VLC_EGENERIC )
411 vlc_mutex_lock( &p_rtcp->object_lock );
412 p_client = p_rtcp->pp_clients[i_pos];
414 p_client->p_stats->u_RR_received++;
415 msg_Dbg( p_this, "RR received %d, SSRC %d",
416 p_client->p_stats->u_RR_received, u_ssrc );
418 p_client->p_stats->u_fraction_lost = bs_read( p_rtcp->bs, 8 );
419 p_client->p_stats->u_pkt_lost = bs_read( p_rtcp->bs, 24 );
420 p_client->p_stats->u_highest_seq_no = bs_read( p_rtcp->bs, 32 );
421 p_client->p_stats->u_jitter = bs_read( p_rtcp->bs, 32 );
422 p_client->p_stats->u_last_SR = bs_read( p_rtcp->bs, 32 );
423 p_client->p_stats->u_delay_since_last_SR = (mtime_t) bs_read( p_rtcp->bs, 32 );
425 /* Magic numbers are from RFC 3550 page 92
426 * 1.0/16.0 = 0.0625 and
429 p_client->p_stats->u_avg_pkt_size = (uint64_t)
430 ( (double)((double)p_client->p_stats->u_sent_pkt_size * (double)(0.0625)) +
431 ((double)(0.9375) * p_client->p_stats->u_avg_pkt_size) );
433 msg_Dbg( p_this, "fract lost %d, packet lost %d, highest seqno %d, "
434 "jitter %d, last SR %d, delay %lld",
435 p_client->p_stats->u_fraction_lost,
436 p_client->p_stats->u_pkt_lost,
437 p_client->p_stats->u_highest_seq_no,
438 p_client->p_stats->u_jitter,
439 p_client->p_stats->u_last_SR,
440 p_client->p_stats->u_delay_since_last_SR );
442 vlc_mutex_unlock( &p_rtcp->object_lock );
447 static int rtcp_decode_SDES( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
449 rtcp_t *p_rtcp = (rtcp_t *) p_this;
455 msg_Dbg( p_this, "decoding record: SDES" );
457 for( i = 0; i < p_pkt->u_report; i++ )
459 rtcp_client_t *p_client = NULL;
463 uint8_t u_length = 0;
467 u_ssrc = bs_read( p_rtcp->bs, 32 );
469 result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
470 if( result == VLC_EGENERIC )
472 result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
473 if( result == VLC_EGENERIC )
477 vlc_mutex_lock( &p_rtcp->object_lock );
478 p_client = p_rtcp->pp_clients[i_pos];
480 u_item = bs_read( p_rtcp->bs, 8 );
483 case RTCP_SDES_CNAME:
485 case RTCP_SDES_EMAIL:
486 case RTCP_SDES_PHONE:
493 u_length = bs_read( p_rtcp->bs, 8 );
494 for( i = 0 ; i < u_length; i++ )
496 psz_name[i] = bs_read( p_rtcp->bs, 8 );
498 SDES_client_item_add( p_client, u_item, psz_name );
502 case RTCP_SDES_PRIV: /* ignoring these */
504 uint8_t u_prefix_len = 0;
505 uint8_t u_length = 0;
506 char psz_prefix_name[255];
509 u_length = bs_read( p_rtcp->bs, 8 );
510 u_prefix_len = bs_read( p_rtcp->bs, 8 );
511 if( u_prefix_len > 254 )
514 for( i=0 ; i < u_prefix_len; i++ )
516 psz_prefix_name[i] = bs_read( p_rtcp->bs, 8 );
518 psz_prefix_name[255] = '\0';
519 SDES_client_item_add( p_client, u_item, psz_prefix_name );
521 for( i=0 ; i < u_length; i++ )
523 psz_name[i] = bs_read( p_rtcp->bs, 8 );
525 psz_name[255] = '\0';
526 SDES_client_item_add( p_client, u_item, psz_name );
533 /* Magic numbers are from RFC 3550 page 92
534 * 1.0/16.0 = 0.0625 and
537 p_client->p_stats->u_avg_pkt_size = (uint64_t)
538 ( (double)((double)p_client->p_stats->u_sent_pkt_size * (double)(0.0625)) +
539 ((double)(0.9375) * p_client->p_stats->u_avg_pkt_size) );
542 vlc_mutex_unlock( &p_rtcp->object_lock );
547 static int rtcp_decode_BYE( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
549 rtcp_t *p_rtcp = (rtcp_t *) p_this;
551 uint8_t u_length = 0;
557 msg_Dbg( p_this, "decoding record: BYE" );
559 u_ssrc = bs_read( p_rtcp->bs, 32 );
560 p_rtcp->pf_del_client( p_this, u_ssrc );
561 u_length = p_pkt->u_length-1;
562 for( i = 0 ; i < u_length; i++ )
564 u_ssrc = bs_read( p_rtcp->bs, 8 );
565 p_rtcp->pf_del_client( p_this, u_ssrc );
570 static int rtcp_decode_APP( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
572 rtcp_t *p_rtcp = (rtcp_t *) p_this;
573 rtcp_client_t *p_client = NULL;
575 char* psz_data = NULL;
584 msg_Dbg( p_this, "decoding record: APP" );
586 u_ssrc = bs_read( p_rtcp->bs, 32 );
588 result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
589 if( result == VLC_EGENERIC )
591 result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
592 if( result == VLC_EGENERIC )
596 vlc_mutex_lock( &p_rtcp->object_lock );
597 p_client = p_rtcp->pp_clients[i_pos];
599 for( i = 0 ; i < 4; i++ )
601 psz_name[i] = bs_read( p_rtcp->bs, 8 );
605 p_pkt->u_payload_type = RTCP_APP;
606 p_pkt->report.app.psz_prefix = strdup( psz_name );
607 p_pkt->report.app.u_prefix_len = 4;
608 p_pkt->u_length -= 4;
610 psz_data = (char *) malloc( p_pkt->u_length );
612 vlc_mutex_unlock( &p_rtcp->object_lock );
616 for( i = 0; i < p_pkt->u_length; i-- )
618 psz_data[i] = bs_read( p_rtcp->bs, 8 );
620 psz_data[p_pkt->u_length] = '\0';
622 p_pkt->report.app.psz_data = strdup( psz_data );
623 p_pkt->report.app.u_length = p_pkt->u_length;
626 vlc_mutex_unlock( &p_rtcp->object_lock );
628 /* Just ignore this packet */
632 /* Decode RTCP packet
633 * Decode incoming RTCP packet and inspect the records types.
635 int rtcp_pkt_decode( vlc_object_t *p_this, rtcp_pkt_t *p_pkt, block_t *p_block )
637 rtcp_t *p_rtcp = (rtcp_t *) p_this;
639 if( !p_pkt && !p_block )
642 bs_init( p_rtcp->bs, p_block->p_buffer, p_block->i_buffer );
644 p_pkt->u_version = bs_read( p_rtcp->bs, 2 );
645 p_pkt->b_padding = bs_read( p_rtcp->bs, 1 ) ? VLC_TRUE : VLC_FALSE;
646 p_pkt->u_report = bs_read( p_rtcp->bs, 5 );
647 p_pkt->u_payload_type = bs_read( p_rtcp->bs, 8 );
648 p_pkt->u_length = bs_read( p_rtcp->bs, 16 );
650 if( p_pkt->u_payload_type != RTCP_SDES )
651 p_pkt->u_ssrc = bs_read( p_rtcp->bs, 32 );
653 msg_Dbg( p_this, "New RTCP packet: version %d, padding %s, count %d, "
654 "type %d, length %d, SSRC %d",
656 p_pkt->b_padding ? "true" : "false",
658 p_pkt->u_payload_type,
662 while( !bs_eof( p_rtcp->bs ) )
666 switch( p_pkt->u_payload_type )
669 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
670 p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
671 rtcp_decode_SR( p_this, p_pkt );
675 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
676 p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
677 rtcp_decode_RR( p_this, p_pkt );
681 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
682 p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
683 rtcp_decode_SDES( p_this, p_pkt );
687 rtcp_decode_BYE( p_this, p_pkt );
689 if( p_rtcp->pf_find_sender( p_this, pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
690 p_rtcp->pf_del_sender( p_this, p_pkt->u_ssrc );
692 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
693 p_rtcp->pf_del_client( p_this, p_pkt->u_ssrc );
695 if( p_rtcp->u_active < p_rtcp->u_members )
697 rtcp_event_t event = EVENT_BYE;
699 p_rtcp->i_next_date = p_rtcp->i_date +
700 (mtime_t) ( (p_rtcp->u_active / p_rtcp->u_members) *
701 (p_rtcp->i_next_date - p_rtcp->i_date) );
702 p_rtcp->i_last_date = p_rtcp->i_date -
704 ( (mtime_t)(p_rtcp->u_active / p_rtcp->u_members) *
705 (p_rtcp->i_date - p_rtcp->i_last_date) );
706 /* schedule for next period */
707 rtcp_schedule( VLC_OBJECT(p_rtcp), p_rtcp->i_next_date, event );
708 p_rtcp->u_members = p_rtcp->u_active;
710 else p_rtcp->u_members++;
714 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
715 p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
716 rtcp_decode_APP( p_this, p_pkt );
727 * Create RTCP records for reporting to server.
729 rtcp_pkt_t *rtcp_pkt_new( vlc_object_t *p_this, int type )
731 rtcp_pkt_t *p_pkt = NULL;
733 p_pkt = (rtcp_pkt_t *) malloc( sizeof( rtcp_pkt_t ) );
737 memset( p_pkt, 0 , sizeof( rtcp_pkt_t ) );
738 p_pkt->u_version = 2;
739 p_pkt->u_payload_type = type;
740 p_pkt->u_length = RTCP_HEADER_LEN;
745 p_pkt->u_length += sizeof(rtcp_SR_t);
748 p_pkt->u_length += sizeof(rtcp_RR_t);
751 p_pkt->u_length += sizeof(rtcp_SDES_t);
752 if( p_pkt->report.sdes.pp_items )
753 p_pkt->u_length += p_pkt->report.sdes.u_items;
756 p_pkt->u_length += sizeof(rtcp_BYE_t);
759 p_pkt->u_length += sizeof(rtcp_APP_t);
768 void rtcp_pkt_del( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
773 switch( p_pkt->u_payload_type )
779 if( p_pkt->report.sdes.pp_items )
783 for( i = 0; i < p_pkt->report.sdes.u_items; i++ )
785 rtcp_SDES_item_t *p_old =
786 p_pkt->report.sdes.pp_items[i];
787 REMOVE_ELEM( p_pkt->report.sdes.pp_items,
788 p_pkt->report.sdes.u_items, i );
789 p_pkt->report.sdes.u_items--;
790 if( p_old->psz_data )
791 free( p_old->psz_data );
799 if( p_pkt->report.app.psz_prefix )
800 free( p_pkt->report.app.psz_prefix );
801 if( p_pkt->report.app.psz_data )
802 free( p_pkt->report.app.psz_data );
805 msg_Err( p_this, "unknown RTCP packet type %d: "
806 "possible leaking of memory.",
807 p_pkt->u_payload_type );
813 block_t *rtcp_encode_SR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
815 rtcp_t *p_rtcp = (rtcp_t *) p_this;
817 bs_t bits, *s = &bits;
818 block_t *p_block = NULL;
819 rtcp_stats_t *p_stats = NULL;
820 rtcp_client_t *p_client = NULL;
824 if( p_pkt->u_payload_type != RTCP_SR )
827 /* FIXME: Maybe this should be a buffer pool instead */
828 p_block = block_New( p_this, p_pkt->u_length );
832 bs_init( s, p_block->p_buffer, p_block->i_buffer );
835 bs_write( s, 2, p_pkt->u_version );
836 bs_write( s, 1, 0 ); /* padding */
837 bs_write( s, 5, p_pkt->u_report );
838 bs_write( s, 8, p_pkt->u_payload_type );
839 bs_write( s, 16, p_pkt->u_length );
840 bs_write( s, 32, p_pkt->u_ssrc );
844 bs_write( s, 32, ((unsigned int)(ntp_time>>32)) ); /* ntp_timestampH */
845 bs_write( s, 32, ((unsigned int)ntp_time) );/* ntp_timestampL */
847 /* FIXME: Make sure to generate a good RTP server timestamp.
848 p_pkt->report.sr.rtp_timestamp = htonl(
849 (unsigned int) ((double)ntp_time.tv_sec +
850 (double)ntp_time.tv_usec/1000000.) * p_mux->rate
851 + session->start_rtptime ); */
852 bs_write( s, 32, p_pkt->report.sr.rtp_timestamp );
853 bs_write( s, 32, p_pkt->report.sr.u_pkt_count );
854 bs_write( s, 32, p_pkt->report.sr.u_octet_count );
857 result = p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos );
858 if( result == VLC_EGENERIC )
860 msg_Err( p_this, "SR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
865 vlc_mutex_lock( &p_rtcp->object_lock );
866 p_client = p_rtcp->pp_clients[i_pos];
868 p_stats = p_client->p_stats;
870 msg_Err( p_this, "SR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
874 bs_write( s, 32, p_stats->l_dest_SSRC );
875 bs_write( s, 8, p_stats->u_fraction_lost );
876 bs_write( s, 24, p_stats->u_pkt_lost );
877 bs_write( s, 32, p_stats->u_highest_seq_no );
878 bs_write( s, 32, p_stats->u_jitter );
879 bs_write( s, 32, p_stats->u_last_SR );
880 bs_write( s, 32, p_stats->u_delay_since_last_SR );
883 vlc_mutex_unlock( &p_rtcp->object_lock );
885 /* possible SR extension */
889 block_t *rtcp_encode_RR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
891 rtcp_t *p_rtcp = (rtcp_t *) p_this;
892 bs_t bits, *s = &bits;
893 block_t *p_block = NULL;
894 rtcp_stats_t *p_stats = NULL;
895 rtcp_client_t *p_client = NULL;
899 if( p_pkt->u_payload_type != RTCP_RR )
902 /* FIXME: Maybe this should be a buffer pool instead */
903 p_block = block_New( p_this, p_pkt->u_length );
907 bs_init( s, p_block->p_buffer, p_block->i_buffer );
910 bs_write( s, 2, p_pkt->u_version );
911 bs_write( s, 1, 0 ); /* padding */
912 bs_write( s, 5, p_pkt->u_report );
913 bs_write( s, 8, p_pkt->u_payload_type );
914 bs_write( s, 16, p_pkt->u_length );
915 bs_write( s, 32, p_pkt->u_ssrc );
918 result = p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos );
919 if( result == VLC_EGENERIC )
921 msg_Err( p_this, "RR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
926 vlc_mutex_lock( &p_rtcp->object_lock );
927 p_client = p_rtcp->pp_clients[i_pos];
929 p_stats = p_client->p_stats;
931 msg_Err( p_this, "RR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
935 bs_write( s, 32, p_stats->l_dest_SSRC );
936 bs_write( s, 8, p_stats->u_fraction_lost );
937 bs_write( s, 24, p_stats->u_pkt_lost );
938 bs_write( s, 32, p_stats->u_highest_seq_no );
939 bs_write( s, 32, p_stats->u_jitter );
940 bs_write( s, 32, p_stats->u_last_RR );
941 bs_write( s, 32, p_stats->u_delay_since_last_RR );
944 vlc_mutex_unlock( &p_rtcp->object_lock );
946 /* possible RR extension */
950 block_t *rtcp_encode_SDES( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
952 bs_t bits, *s = &bits;
953 block_t *p_block = NULL;
956 if( p_pkt->u_payload_type != RTCP_SDES )
959 /* FIXME: Maybe this should be a buffer pool instead */
960 p_block = block_New( p_this, p_pkt->u_length );
964 bs_init( s, p_block->p_buffer, p_block->i_buffer );
967 bs_write( s, 2, p_pkt->u_version );
968 bs_write( s, 1, 0 ); /* padding */
969 bs_write( s, 5, p_pkt->u_report ); /* Number of SSRC/CSRC chunks */
970 bs_write( s, 8, p_pkt->u_payload_type );
971 bs_write( s, 16, p_pkt->u_length );
972 bs_write( s, 32, p_pkt->u_ssrc );
975 for( i_chunks = 0; i_chunks < p_pkt->u_report; i_chunks++ )
979 for( i_item = 0 ; i_item < p_pkt->report.sdes.u_items; i_item++ )
981 uint32_t i_count = strlen( p_pkt->report.sdes.pp_items[i_item]->psz_data );
982 uint8_t u_octet = i_count / 8; /* Octect count ??*/
983 rtcp_SDES_item_t *p_item = p_pkt->report.sdes.pp_items[i_item];
984 uint32_t i_pos, i_pad, i_padding;
986 bs_write( s, 8, p_item->u_type );
987 bs_write( s, 8, u_octet );
989 for( i_pos = 0; i_pos < i_count; i_pos++ )
991 /* FIXME: must be UTF 8 encoded */
992 bs_write( s, 8, p_item->psz_data[i_pos] );
995 /* do we need padding to 32 bit boundary? */
997 if( ((i_count + 2) % 4) != 0 )
998 i_padding = (i_count + 2) - (((i_count + 2) % 4) << 2);
999 for( i_pad = 0; i_pad < i_padding; i_pad++ )
1001 bs_write( s, 8, 0 );
1008 block_t *rtcp_encode_BYE( vlc_object_t *p_this, rtcp_pkt_t *p_pkt, char *psz_reason )
1010 bs_t bits, *s = &bits;
1011 block_t *p_block = NULL;
1012 uint32_t i_count = strlen( psz_reason );
1013 uint8_t u_octet = i_count / 8; /* Octect count ??*/
1014 int32_t i_pos, i_pad, i_padding;
1016 if( p_pkt->u_payload_type != RTCP_BYE )
1019 /* FIXME: Maybe this should be a buffer pool instead */
1020 p_block = block_New( p_this, p_pkt->u_length );
1024 bs_init( s, p_block->p_buffer, p_block->i_buffer );
1026 /* Fill in header */
1027 bs_write( s, 2, p_pkt->u_version );
1028 bs_write( s, 1, 0 ); /* padding */
1029 bs_write( s, 5, p_pkt->u_report ); /* Number of SSRC/CSRC chunks */
1030 bs_write( s, 8, p_pkt->u_payload_type );
1031 bs_write( s, 16, p_pkt->u_length );
1032 bs_write( s, 32, p_pkt->u_ssrc );
1034 /* Give reason for leaving */
1035 //FIXME: bs_write( s, 8, p_item->u_type );
1036 bs_write( s, 8, u_octet );
1038 for( i_pos = 0; i_pos < i_count; i_pos++ )
1040 /* FIXME: must be UTF 8 encoded */
1041 bs_write( s, 8, psz_reason[i_pos] );
1044 /* do we need padding to 32 bit boundary? */
1046 if( ((i_count + 2) % 4) != 0 )
1047 i_padding = (i_count + 2) - (((i_count + 2) % 4) << 2);
1048 for( i_pad = 0; i_pad < i_padding; i_pad++ )
1050 bs_write( s, 8, 0 );