]> git.sesse.net Git - vlc/blob - modules/mux/rtp/rtcp.c
Fix description
[vlc] / modules / mux / rtp / rtcp.c
1 /*****************************************************************************
2  * rtcp.c: RTP/RTCP source file
3  *****************************************************************************
4  * Copyright (C) 2005-2007 M2X
5  *
6  * $Id$
7  *
8  * Authors: Jean-Paul Saman <jpsaman #_at_# videolan dot org>
9  *
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.
14  *
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.
19  *
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  *****************************************************************************/
24
25 #include <netinet/in.h>
26 #include <sys/time.h>
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc_common.h>
33 #include <vlc_bits.h>
34 #include <vlc_block.h>
35
36 #include "rtp.h"
37 #include "rtcp.h"
38
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 );
41
42 /* SDES support functions */
43 static int SDES_client_item_add( rtcp_client_t *p_client, int i_item, char *psz_name )
44 {
45     rtcp_SDES_item_t *p_item = NULL;
46     
47     p_item = (rtcp_SDES_item_t *) malloc( sizeof( rtcp_SDES_item_t ) );
48     if( !p_item )
49         return VLC_ENOMEM;
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 );
55     return VLC_EGENERIC;
56 }
57
58 static int SDES_client_item_del( rtcp_client_t *p_client )
59 {
60     uint32_t i = 0;
61
62     for( i=0; i < p_client->i_items; i++ )
63     {
64         rtcp_SDES_item_t *p_old = p_client->pp_sdes[i];
65         REMOVE_ELEM( p_client->pp_sdes, p_client->i_items, i );
66         p_client->i_items--;
67         if( p_old->psz_data)
68             free( p_old->psz_data );
69         free( p_old );
70     }
71     return VLC_SUCCESS;
72 }
73
74 int rtcp_add_client( vlc_object_t *p_this, uint32_t u_ssrc, uint32_t *i_pos )
75 {
76     rtcp_t *p_rtcp = (rtcp_t *) p_this;
77     rtcp_client_t *p_client = NULL;
78
79     vlc_object_lock( p_rtcp );
80     p_client = (rtcp_client_t*) malloc( sizeof(rtcp_client_t) );
81     if( !p_client )
82         return VLC_ENOMEM;
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 );
88     p_rtcp->i_clients++;
89     p_rtcp->u_clients++;
90     vlc_object_unlock( p_rtcp );
91     return VLC_SUCCESS;
92 }
93
94 int rtcp_del_client( vlc_object_t *p_this, uint32_t u_ssrc )
95 {
96     rtcp_t *p_rtcp = (rtcp_t *) p_this;
97     uint32_t i_pos = 0;
98
99     vlc_object_lock( p_rtcp );
100     if( p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos ) == VLC_SUCCESS )
101     {
102         rtcp_client_t *p_old = p_rtcp->pp_clients[i_pos];
103
104         p_old->b_deleted = true;
105         p_old->i_timeout = 5 * (p_rtcp->i_date - p_rtcp->i_last_date) +
106                            p_rtcp->i_next_date;
107         p_rtcp->u_clients--;
108         /* BYE message is sent by rtcp_destroy_client() */
109     }
110     vlc_object_unlock( p_rtcp );
111     return VLC_SUCCESS;
112 }
113
114 /* rtcp_cleanup_clients should not be called too often */
115 int rtcp_cleanup_clients( vlc_object_t *p_this )
116 {
117     rtcp_t *p_rtcp = (rtcp_t *) p_this;
118     uint32_t i = 0;
119
120     vlc_object_lock( p_rtcp );
121     for( i=0; i < p_rtcp->i_clients; i++ )
122     {
123         rtcp_client_t *p_old = p_rtcp->pp_clients[i];
124
125         if( p_old->b_deleted &&
126            (p_old->i_timeout > mdate()) )
127         {
128             REMOVE_ELEM( p_rtcp->pp_clients, p_rtcp->i_clients, i );
129             p_rtcp->i_clients--;
130             SDES_client_item_del( p_old );
131             free( p_old );
132         }
133     }
134     vlc_object_unlock( p_rtcp );
135     return VLC_SUCCESS;
136 }
137
138 /* Close communication with clients and release allocated objects */
139 int rtcp_destroy_clients( vlc_object_t *p_this )
140 {
141     rtcp_t *p_rtcp = (rtcp_t *) p_this;
142     uint32_t i = 0;
143
144     for( i=0; i < p_rtcp->i_clients; i++ )
145     {
146         rtcp_pkt_t *pkt = NULL;
147         rtcp_client_t *p_old = p_rtcp->pp_clients[i];
148
149         p_rtcp->pf_del_client( p_this, p_old->u_ssrc );
150     pkt = rtcp_pkt_new( p_this, RTCP_BYE );
151     if( pkt )
152     {
153         block_t *p_block = NULL;
154         p_block = rtcp_encode_BYE( p_this, pkt, strdup("server is leaving") );
155             /* FIXME:
156              * if( p_block )
157          *    send_RTCP( p_this, p_block );
158              */
159     }
160             
161     }
162     /* wait till all clients have been signalled */
163     while( p_rtcp->i_clients != 0 )
164     {
165         p_rtcp->pf_cleanup_clients( p_this );
166         msleep( 500 );
167     }
168     return VLC_SUCCESS;
169 }
170
171 /*  rtcp_find_client should be called with the object lock held.
172  *  vlc_mutex_lock( &p_rtcp->obj_lock );
173  */
174 int rtcp_find_client( vlc_object_t *p_this, uint32_t u_ssrc, uint32_t *i_pos )
175 {
176     rtcp_t *p_rtcp = (rtcp_t *) p_this;
177     uint32_t i = 0;
178
179     for( i=0; i < p_rtcp->i_clients; i++ )
180     {
181         if( p_rtcp->pp_clients[i]->u_ssrc == u_ssrc )
182         {
183             *i_pos = i;
184             return VLC_SUCCESS;
185         }
186     }
187     *i_pos = -1;
188     return VLC_EGENERIC;
189 }
190
191 /*--------------------------------------------------------------------------
192  * rtcp_interval - Calculate the interval in seconds for sending RTCP packets.
193  *--------------------------------------------------------------------------
194  */
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 )
197 {
198     rtcp_t *p_rtcp = (rtcp_t *) p_this;
199     rtcp_client_t *p_client = NULL;
200     uint32_t i_rtcp_min = 5; /* seconds */
201     uint32_t i_pos = 0;
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;
206
207     if( b_first )
208         i_rtcp_min = (i_rtcp_min >> 1);
209
210     if( (double)(p_rtcp->u_active) <= (double)(p_rtcp->u_clients * 0.25) )
211     {
212         if( b_sender )
213         {
214             i_bandwidth = i_bandwidth * 0.25;
215             n = p_rtcp->u_active;
216         }
217         else
218         {
219             i_bandwidth = i_bandwidth * ( 1 - 0.25 );
220             n = n - p_rtcp->u_active;
221         }
222     }
223     /* calculate average time between reports */
224     p_client = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
225     if( !p_client )
226         return -1;
227         
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);
233
234     return (uint64_t)i_interval;
235 }
236
237 /*--------------------------------------------------------------------------
238  * rtcp_expire - decides to sent an RTCP report or a BYE record
239  *--------------------------------------------------------------------------
240  */
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 )
243 {
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;
248     uint32_t i_pos = 0;
249
250     p_client = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
251     if( !p_client )
252         return;
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;
257
258     switch( rtcp_event )
259     {
260         case EVENT_BYE:
261             if( p_rtcp->i_next_date <= p_rtcp->i_date )
262                 send_RTCP( p_this, rtcp_event );
263             else
264                 rtcp_schedule( p_this, p_rtcp->i_next_date, rtcp_event );
265             break;
266
267         case EVENT_REPORT:
268             if( p_rtcp->i_next_date <= p_rtcp->i_date )
269             {
270                 send_RTCP( p_this, rtcp_event );
271
272                 /* Magic numbers are from RFC 3550 page 92
273                  * 1.0/16.0 = 0.0625 and
274                  * 15.0/16.0 = 0.9375
275                  */
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 ) );
279
280                 /* recalculate */
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 );
285                 *b_first = false;
286             }
287             else
288             {
289                 rtcp_schedule( p_this, p_rtcp->i_next_date, rtcp_event );
290             }
291             break;
292     }
293     p_rtcp->i_date = p_rtcp->i_next_date;
294 }
295
296 /*--------------------------------------------------------------------------
297  * Local functions prototoypes
298  *--------------------------------------------------------------------------
299  */
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 );
306
307 /*--------------------------------------------------------------------------
308  * Local functions
309  *--------------------------------------------------------------------------
310  */
311 static int rtcp_decode_SR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
312 {
313     rtcp_t *p_rtcp = (rtcp_t *) p_this;
314     unsigned int i = 0;
315
316     if( !p_pkt )
317         return VLC_EGENERIC;
318
319     msg_Dbg( p_this, "decoding record: SR" );
320
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*/
328
329     /* parse report block */
330     for( i=0; i < p_pkt->u_report; i++ )
331     {
332         rtcp_client_t *p_client = NULL;
333         uint32_t i_pos = 0;
334         uint32_t u_ssrc = 0;
335         int   result = 0;
336
337         u_ssrc = bs_read( p_rtcp->bs, 32 );
338
339         result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
340         if( result == VLC_EGENERIC )
341         {
342             result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
343             if( result == VLC_EGENERIC )
344                 return VLC_ENOMEM;
345         }
346         vlc_object_lock( p_rtcp );
347         p_client = p_rtcp->pp_clients[i_pos];
348
349         p_client->p_stats->u_SR_received++;
350         p_client->p_stats->u_pkt_count++;
351         p_client->p_stats->u_octet_count++;
352
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,
357             p_pkt->u_ssrc );
358         
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 );
365
366         /* Magic numbers are from RFC 3550 page 92
367          * 1.0/16.0 = 0.0625 and
368          * 15.0/16.0 = 0.9375
369          */
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) );
373
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 );
382         p_client = NULL;
383         vlc_object_unlock( p_rtcp );
384     }
385     return VLC_SUCCESS;
386 }
387
388 static int rtcp_decode_RR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
389 {
390     rtcp_t *p_rtcp = (rtcp_t *) p_this;
391     unsigned int i = 0;
392
393     if( !p_pkt )
394         return VLC_EGENERIC;
395
396     msg_Dbg( p_this, "decoding record: RR" );
397
398     for( i=0; i < p_pkt->u_report; i++ )
399     {
400         rtcp_client_t *p_client = NULL;
401         uint32_t i_pos = 0;
402         uint32_t u_ssrc = 0;
403         int   result = 0;
404
405         u_ssrc = bs_read( p_rtcp->bs, 32 );
406
407         result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
408         if( result == VLC_EGENERIC )
409         {
410             result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
411             if( result == VLC_EGENERIC )
412                 return VLC_ENOMEM;
413         }
414
415         vlc_object_lock( p_rtcp );
416         p_client = p_rtcp->pp_clients[i_pos];
417
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 );
421
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 );
428
429         /* Magic numbers are from RFC 3550 page 92
430          * 1.0/16.0 = 0.0625 and
431          * 15.0/16.0 = 0.9375
432          */
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) );
436
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 );
445         p_client = NULL;
446         vlc_object_unlock( p_rtcp );
447     }
448     return VLC_SUCCESS;
449 }
450
451 static int rtcp_decode_SDES( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
452 {
453     rtcp_t *p_rtcp = (rtcp_t *) p_this;
454     unsigned int i = 0;
455
456     if( !p_pkt )
457         return VLC_EGENERIC;
458
459     msg_Dbg( p_this, "decoding record: SDES" );
460
461     for( i = 0; i < p_pkt->u_report; i++ )
462     {
463         rtcp_client_t *p_client = NULL;
464         uint32_t i_pos = 0;
465         uint32_t u_ssrc = 0;
466         uint8_t  u_item = 0;
467         uint8_t  u_length = 0;
468         int   i = 0;
469         int   result = 0;
470
471         u_ssrc = bs_read( p_rtcp->bs, 32 );
472
473         result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
474         if( result == VLC_EGENERIC )
475         {
476             result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
477             if( result == VLC_EGENERIC )
478                 return VLC_ENOMEM;
479         }
480
481         vlc_object_lock( p_rtcp );
482         p_client = p_rtcp->pp_clients[i_pos];
483
484         u_item = bs_read( p_rtcp->bs, 8 );
485         switch( u_item )
486         {
487             case RTCP_SDES_CNAME:
488             case RTCP_SDES_NAME:
489             case RTCP_SDES_EMAIL:
490             case RTCP_SDES_PHONE:
491             case RTCP_SDES_LOC:
492             case RTCP_SDES_TOOL:
493             case RTCP_SDES_NOTE:
494             {
495                 char psz_name[255];
496
497                 u_length = bs_read( p_rtcp->bs, 8 );
498                 for( i = 0 ; i < u_length; i++ )
499                 {
500                     psz_name[i] = bs_read( p_rtcp->bs, 8 );
501                 }
502                 SDES_client_item_add( p_client, u_item, psz_name );
503             }
504             break;
505
506             case RTCP_SDES_PRIV: /* ignoring these */
507             {
508                 uint8_t u_prefix_len = 0;
509                 uint8_t u_length = 0;
510                 char psz_prefix_name[255];
511                 char psz_name[255];
512
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 )
516                     u_prefix_len = 254;
517
518                 for( i=0 ; i < u_prefix_len; i++ )
519                 {
520                     psz_prefix_name[i] = bs_read( p_rtcp->bs, 8 );
521                 }
522                 psz_prefix_name[255] = '\0';
523                 SDES_client_item_add( p_client, u_item, psz_prefix_name );
524
525                 for( i=0 ; i < u_length; i++ )
526                 {
527                     psz_name[i] = bs_read( p_rtcp->bs, 8 );
528                 }
529                 psz_name[255] = '\0';
530                 SDES_client_item_add( p_client, u_item, psz_name );
531             }
532             break;
533
534             default:
535                 return VLC_EGENERIC;
536         }
537         /* Magic numbers are from RFC 3550 page 92
538          * 1.0/16.0 = 0.0625 and
539          * 15.0/16.0 = 0.9375
540          */
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) );
544
545         p_client = NULL;
546         vlc_object_unlock( p_rtcp );
547     }
548     return VLC_SUCCESS;
549 }
550
551 static int rtcp_decode_BYE( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
552 {
553     rtcp_t    *p_rtcp = (rtcp_t *) p_this;
554     uint32_t  u_ssrc = 0;
555     uint8_t   u_length = 0;
556     int       i = 0;
557
558     if( !p_pkt )
559         return VLC_EGENERIC;
560
561     msg_Dbg( p_this, "decoding record: BYE" );
562
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++ )
567     {
568         u_ssrc = bs_read( p_rtcp->bs, 8 );
569         p_rtcp->pf_del_client( p_this, u_ssrc );
570     }
571     return VLC_SUCCESS;
572 }
573
574 static int rtcp_decode_APP( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
575 {
576     rtcp_t        *p_rtcp = (rtcp_t *) p_this;
577     rtcp_client_t *p_client = NULL;
578     char  psz_name[4];
579     char* psz_data = NULL;
580     uint32_t u_ssrc = 0;
581     uint32_t i_pos = 0;
582     uint32_t i = 0;
583     int   result = 0;
584
585     if( !p_pkt )
586         return VLC_EGENERIC;
587
588     msg_Dbg( p_this, "decoding record: APP" );
589
590     u_ssrc = bs_read( p_rtcp->bs, 32 );
591
592     result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
593     if( result == VLC_EGENERIC )
594     {
595         result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
596         if( result == VLC_EGENERIC )
597             return VLC_ENOMEM;
598     }
599
600     vlc_object_lock( p_rtcp );
601     p_client = p_rtcp->pp_clients[i_pos];
602
603     for( i = 0 ; i < 4; i++ )
604     {
605         psz_name[i] = bs_read( p_rtcp->bs, 8 );
606     }
607     psz_name[4] = '\0';
608     
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;
613
614     psz_data = (char *) malloc( p_pkt->u_length );
615     if( !psz_data ) {
616         vlc_object_unlock( p_rtcp );
617         return VLC_EGENERIC;
618     }
619
620     for( i = 0; i < p_pkt->u_length; i-- )
621     {
622         psz_data[i] = bs_read( p_rtcp->bs, 8 );
623     }
624     psz_data[p_pkt->u_length] = '\0';
625
626     p_pkt->report.app.psz_data = strdup( psz_data );
627     p_pkt->report.app.u_length = p_pkt->u_length;
628
629     p_client = NULL;
630     vlc_object_unlock( p_rtcp );
631
632     /* Just ignore this packet */
633     return VLC_SUCCESS;
634 }
635
636 /* Decode RTCP packet
637  * Decode incoming RTCP packet and inspect the records types.
638  */
639 int rtcp_pkt_decode( vlc_object_t *p_this, rtcp_pkt_t *p_pkt, block_t *p_block )
640 {
641     rtcp_t *p_rtcp = (rtcp_t *) p_this;
642
643     if( !p_pkt && !p_block )
644         return VLC_EGENERIC;
645
646     bs_init( p_rtcp->bs, p_block->p_buffer, p_block->i_buffer );
647
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 );
653
654     if( p_pkt->u_payload_type != RTCP_SDES )
655         p_pkt->u_ssrc = bs_read( p_rtcp->bs, 32 );
656
657     msg_Dbg( p_this, "New RTCP packet: version %d, padding %s, count %d, "
658                      "type %d, length %d, SSRC %d",
659         p_pkt->u_version,
660         p_pkt->b_padding ? "true" : "false",
661         p_pkt->u_report,
662         p_pkt->u_payload_type,
663         p_pkt->u_length,
664         p_pkt->u_ssrc );
665
666     while( !bs_eof( p_rtcp->bs ) )
667     {
668         uint32_t i_pos = 0;
669         
670         switch( p_pkt->u_payload_type )
671         {
672             case RTCP_SR:
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 );
676                 break;
677
678             case RTCP_RR:
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 );
682                 break;
683
684             case RTCP_SDES:
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 );
688                 break;
689
690             case RTCP_BYE:
691                 rtcp_decode_BYE( p_this, p_pkt );
692 #if 0
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 );
695 #endif
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 );
698
699                 if( p_rtcp->u_active < p_rtcp->u_members )
700                 {
701                     rtcp_event_t event = EVENT_BYE;
702                     
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 -
707                                         (mtime_t)
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;
713                 }
714                 else p_rtcp->u_members++;
715                 break;
716
717             case RTCP_APP:
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 );
721                 break;
722
723             default:
724                 return VLC_EGENERIC;
725         }
726     }
727     return VLC_SUCCESS;
728 }
729
730 /*
731  * Create RTCP records for reporting to server.
732  */
733 rtcp_pkt_t *rtcp_pkt_new( vlc_object_t *p_this, int type )
734 {
735     rtcp_pkt_t *p_pkt = NULL;
736
737     p_pkt = (rtcp_pkt_t *) malloc( sizeof( rtcp_pkt_t ) );
738     if( !p_pkt )
739         return NULL;
740
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;
745
746     switch( type )
747     {
748         case RTCP_SR:
749             p_pkt->u_length += sizeof(rtcp_SR_t);
750             break;
751         case RTCP_RR:
752             p_pkt->u_length += sizeof(rtcp_RR_t);
753             break;
754         case RTCP_SDES:
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;
758             break;
759         case RTCP_BYE:
760             p_pkt->u_length += sizeof(rtcp_BYE_t);
761             break;
762         case RTCP_APP:
763             p_pkt->u_length += sizeof(rtcp_APP_t);
764             break;
765         default:
766             free(p_pkt);
767             return NULL;
768     }
769     return p_pkt;
770 }
771
772 void rtcp_pkt_del( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
773 {
774     if( !p_pkt )
775         return;
776
777     switch( p_pkt->u_payload_type )
778     {
779         case RTCP_SR:
780         case RTCP_RR:
781             break;
782         case RTCP_SDES:
783             if( p_pkt->report.sdes.pp_items )
784             {
785                 uint32_t i = 0;
786
787                 for( i = 0; i < p_pkt->report.sdes.u_items; i++ )
788                 {
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 );
796                     free( p_old );
797                 }
798             }
799             break;
800         case RTCP_BYE:
801             break;
802         case RTCP_APP:
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 );
807             break;
808         default:
809             msg_Err( p_this, "unknown RTCP packet type %d: "
810                              "possible leaking of memory.",
811                             p_pkt->u_payload_type );
812             break;
813     }
814     free( p_pkt );
815 }
816
817 block_t *rtcp_encode_SR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
818 {
819     rtcp_t *p_rtcp = (rtcp_t *) p_this;
820     mtime_t ntp_time;
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;
825     uint32_t i_pos = 0;
826     int result = 0;
827
828     if( p_pkt->u_payload_type != RTCP_SR )
829         return NULL;
830
831     /* FIXME: Maybe this should be a buffer pool instead */
832     p_block = block_New( p_this, p_pkt->u_length );
833     if( !p_block )
834         return NULL;
835
836     bs_init( s, p_block->p_buffer, p_block->i_buffer );
837
838     /* Fill in header */
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 );
845
846     /* sender info */
847     ntp_time = mdate();
848     bs_write( s, 32, ((unsigned int)(ntp_time>>32)) ); /* ntp_timestampH */
849     bs_write( s, 32, ((unsigned int)ntp_time) );/* ntp_timestampL */
850
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 );
859
860     /* report block */
861     result = p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos );
862     if( result == VLC_EGENERIC )
863     {
864         msg_Err( p_this, "SR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
865         free( p_block );
866         return NULL;
867     }
868
869     vlc_object_lock( p_rtcp );
870     p_client = p_rtcp->pp_clients[i_pos];
871
872     p_stats = p_client->p_stats;
873     if( !p_stats ) {
874         msg_Err( p_this, "SR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
875         free( p_block );
876         return NULL;
877     }
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 );
885
886     p_client = NULL;
887     vlc_object_unlock( p_rtcp );
888
889     /* possible SR extension */
890     return p_block;
891 }
892
893 block_t *rtcp_encode_RR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
894 {
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;
900     uint32_t i_pos = 0;
901     int result = 0;
902
903     if( p_pkt->u_payload_type != RTCP_RR )
904         return NULL;
905
906     /* FIXME: Maybe this should be a buffer pool instead */
907     p_block = block_New( p_this, p_pkt->u_length );
908     if( !p_block )
909         return NULL;
910
911     bs_init( s, p_block->p_buffer, p_block->i_buffer );
912
913     /* Fill in header */
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 );
920
921     /* report block */
922     result = p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos );
923     if( result == VLC_EGENERIC )
924     {
925         msg_Err( p_this, "RR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
926         free( p_block );
927         return NULL;
928     }
929
930     vlc_object_lock( p_rtcp );
931     p_client = p_rtcp->pp_clients[i_pos];
932
933     p_stats = p_client->p_stats;
934     if( !p_stats ) {
935         msg_Err( p_this, "RR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
936         free( p_block );
937         return NULL;
938     }
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 );
946
947     p_client = NULL;
948     vlc_object_unlock( p_rtcp );
949
950     /* possible RR extension */
951     return p_block;
952 }
953
954 block_t *rtcp_encode_SDES( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
955 {
956     bs_t bits, *s = &bits;
957     block_t *p_block = NULL;
958     uint32_t i_chunks;
959
960     if( p_pkt->u_payload_type != RTCP_SDES )
961         return NULL;
962
963     /* FIXME: Maybe this should be a buffer pool instead */
964     p_block = block_New( p_this, p_pkt->u_length );
965     if( !p_block )
966         return NULL;
967
968     bs_init( s, p_block->p_buffer, p_block->i_buffer );
969
970     /* Fill in header */
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 );
977
978     /* fill in record */
979     for( i_chunks = 0; i_chunks < p_pkt->u_report; i_chunks++ )
980     {
981         uint32_t i_item;
982
983         for( i_item = 0 ; i_item < p_pkt->report.sdes.u_items; i_item++ )
984         {
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;
989
990             bs_write( s, 8, p_item->u_type );
991             bs_write( s, 8, u_octet );
992
993             for( i_pos = 0; i_pos < i_count; i_pos++ )
994             {
995                 /* FIXME: must be UTF 8 encoded */
996                 bs_write( s, 8, p_item->psz_data[i_pos] );
997             }
998
999             /* do we need padding to 32 bit boundary? */
1000             i_padding = 0;
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++ )
1004             {
1005                 bs_write( s, 8, 0 );
1006             }
1007         }
1008     }
1009     return p_block;
1010 }
1011
1012 block_t *rtcp_encode_BYE( vlc_object_t *p_this, rtcp_pkt_t *p_pkt, char *psz_reason )
1013 {
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;
1019
1020     if( p_pkt->u_payload_type != RTCP_BYE )
1021         return NULL;
1022
1023     /* FIXME: Maybe this should be a buffer pool instead */
1024     p_block = block_New( p_this, p_pkt->u_length );
1025     if( !p_block )
1026         return NULL;
1027
1028     bs_init( s, p_block->p_buffer, p_block->i_buffer );
1029
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 );
1037
1038     /* Give reason for leaving */
1039     //FIXME: bs_write( s, 8, p_item->u_type );
1040     bs_write( s, 8, u_octet );
1041     
1042     for( i_pos = 0; i_pos < i_count; i_pos++ )
1043     {
1044         /* FIXME: must be UTF 8 encoded */
1045         bs_write( s, 8, psz_reason[i_pos] );
1046     }
1047
1048     /* do we need padding to 32 bit boundary? */
1049     i_padding = 0;
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++ )
1053     {
1054         bs_write( s, 8, 0 );
1055     }
1056     return p_block;
1057 }