]> git.sesse.net Git - vlc/blob - modules/mux/rtp/rtcp.c
Numerous compile fixes.
[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 <stdlib.h>
26 #include <netinet/in.h>
27 #include <sys/time.h>
28
29 #include <vlc/vlc.h>
30 #include <vlc_bits.h>
31 #include <vlc_block.h>
32
33 #include "rtp.h"
34 #include "rtcp.h"
35
36 void send_RTCP( vlc_object_t *p_this, rtcp_event_t );
37 void rtcp_schedule( vlc_object_t *p_this, mtime_t, rtcp_event_t );
38
39 /* SDES support functions */
40 static int SDES_client_item_add( rtcp_client_t *p_client, int i_item, char *psz_name )
41 {
42     rtcp_SDES_item_t *p_item = NULL;
43         
44     p_item = (rtcp_SDES_item_t *) malloc( sizeof( rtcp_SDES_item_t ) );
45     if( !p_item )
46         return VLC_ENOMEM;
47     p_item->u_type = i_item;
48     p_item->psz_data = strdup( psz_name );
49     p_item->i_index = p_client->i_items + 1;;
50     INSERT_ELEM( p_client->pp_sdes, p_client->i_items,
51                  p_item->i_index, p_item );
52     return VLC_EGENERIC;
53 }
54
55 static int SDES_client_item_del( rtcp_client_t *p_client )
56 {
57     uint32_t i = 0;
58
59     for( i=0; i < p_client->i_items; i++ )
60     {
61         rtcp_SDES_item_t *p_old = p_client->pp_sdes[i];
62         REMOVE_ELEM( p_client->pp_sdes, p_client->i_items, i );
63         p_client->i_items--;
64         if( p_old->psz_data)
65             free( p_old->psz_data );
66         free( p_old );
67     }
68     return VLC_SUCCESS;
69 }
70
71 int rtcp_add_client( vlc_object_t *p_this, uint32_t u_ssrc, uint32_t *i_pos )
72 {
73     rtcp_t *p_rtcp = (rtcp_t *) p_this;
74     rtcp_client_t *p_client = NULL;
75
76     vlc_mutex_lock( &p_rtcp->object_lock );
77     p_client = (rtcp_client_t*) malloc( sizeof(rtcp_client_t) );
78     if( !p_client )
79         return VLC_ENOMEM;
80     p_client->i_index = p_rtcp->i_clients + 1;
81     p_client->b_deleted = VLC_FALSE;
82     *i_pos = p_client->i_index ;
83     INSERT_ELEM( p_rtcp->pp_clients, p_rtcp->i_clients,
84                  p_client->i_index, p_client );
85     p_rtcp->i_clients++;
86     p_rtcp->u_clients++;
87     vlc_mutex_unlock( &p_rtcp->object_lock );
88     return VLC_SUCCESS;
89 }
90
91 int rtcp_del_client( vlc_object_t *p_this, uint32_t u_ssrc )
92 {
93     rtcp_t *p_rtcp = (rtcp_t *) p_this;
94     uint32_t i_pos = 0;
95
96     vlc_mutex_lock( &p_rtcp->object_lock );
97     if( p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos ) == VLC_SUCCESS )
98     {
99         rtcp_client_t *p_old = p_rtcp->pp_clients[i_pos];
100
101         p_old->b_deleted = VLC_TRUE;
102         p_old->i_timeout = 5 * (p_rtcp->i_date - p_rtcp->i_last_date) +
103                            p_rtcp->i_next_date;
104         p_rtcp->u_clients--;
105         /* BYE message is sent by rtcp_destroy_client() */
106     }
107     vlc_mutex_unlock( &p_rtcp->object_lock );
108     return VLC_SUCCESS;
109 }
110
111 /* rtcp_cleanup_clients should not be called too often */
112 int rtcp_cleanup_clients( vlc_object_t *p_this )
113 {
114     rtcp_t *p_rtcp = (rtcp_t *) p_this;
115     uint32_t i = 0;
116
117     vlc_mutex_lock( &p_rtcp->object_lock );
118     for( i=0; i < p_rtcp->i_clients; i++ )
119     {
120         rtcp_client_t *p_old = p_rtcp->pp_clients[i];
121
122         if( p_old->b_deleted &&
123            (p_old->i_timeout > mdate()) )
124         {
125             REMOVE_ELEM( p_rtcp->pp_clients, p_rtcp->i_clients, i );
126             p_rtcp->i_clients--;
127             SDES_client_item_del( p_old );
128             free( p_old );
129         }
130     }
131     vlc_mutex_unlock( &p_rtcp->object_lock );
132     return VLC_SUCCESS;
133 }
134
135 /* Close communication with clients and release allocated objects */
136 int rtcp_destroy_clients( vlc_object_t *p_this )
137 {
138     rtcp_t *p_rtcp = (rtcp_t *) p_this;
139     uint32_t i = 0;
140
141     for( i=0; i < p_rtcp->i_clients; i++ )
142     {
143         rtcp_pkt_t *pkt = NULL;
144         rtcp_client_t *p_old = p_rtcp->pp_clients[i];
145
146         p_rtcp->pf_del_client( p_this, p_old->u_ssrc );
147         pkt = rtcp_pkt_new( p_this, RTCP_BYE );
148         if( pkt )
149         {
150             block_t *p_block = NULL;
151             p_block = rtcp_encode_BYE( p_this, pkt, strdup("server is leaving") );
152             /* FIXME: 
153              * if( p_block )
154              *    send_RTCP( p_this, p_block );
155              */
156         }
157                         
158     }
159     /* wait till all clients have been signalled */
160     while( p_rtcp->i_clients != 0 )
161     {
162         p_rtcp->pf_cleanup_clients( p_this );
163         msleep( 500 );
164     }
165     return VLC_SUCCESS;
166 }
167
168 /*  rtcp_find_client should be called with the object lock held.
169  *  vlc_mutex_lock( &p_rtcp->obj_lock );
170  */
171 int rtcp_find_client( vlc_object_t *p_this, uint32_t u_ssrc, uint32_t *i_pos )
172 {
173     rtcp_t *p_rtcp = (rtcp_t *) p_this;
174     uint32_t i = 0;
175
176     for( i=0; i < p_rtcp->i_clients; i++ )
177     {
178         if( p_rtcp->pp_clients[i]->u_ssrc == u_ssrc )
179         {
180             *i_pos = i;
181             return VLC_SUCCESS;
182         }
183     }
184     *i_pos = -1;
185     return VLC_EGENERIC;
186 }
187
188 /*--------------------------------------------------------------------------
189  * rtcp_interval - Calculate the interval in seconds for sending RTCP packets.
190  *--------------------------------------------------------------------------
191  */
192 uint64_t rtcp_interval( vlc_object_t *p_this, uint64_t u_bandwidth, uint32_t u_ssrc,
193                         vlc_bool_t b_sender, vlc_bool_t b_first )
194 {
195     rtcp_t *p_rtcp = (rtcp_t *) p_this;
196         rtcp_client_t *p_client = NULL;
197     uint32_t i_rtcp_min = 5; /* seconds */
198         uint32_t i_pos = 0;
199         double i_bandwidth = u_bandwidth;
200     const double i_compensation = 2.71828 - 1.5;
201     double i_interval = 0;
202     int n = p_rtcp->i_clients;
203
204     if( b_first )
205         i_rtcp_min = (i_rtcp_min >> 1);
206
207     if( (double)(p_rtcp->u_active) <= (double)(p_rtcp->u_clients * 0.25) )
208     {
209         if( b_sender )
210         {
211             i_bandwidth = i_bandwidth * 0.25;
212             n = p_rtcp->u_active;
213         }
214         else
215         {
216             i_bandwidth = i_bandwidth * ( 1 - 0.25 );
217             n = n - p_rtcp->u_active;
218         }
219     }
220     /* calculate average time between reports */
221     p_client = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
222     if( !p_client )
223         return -1;
224                 
225         i_interval = p_client->p_stats->u_avg_pkt_size * ( n / i_bandwidth );
226     if( i_interval < i_rtcp_min )
227         i_interval = i_rtcp_min;
228     i_interval = i_interval * ( drand48() + 0.5 );
229     i_interval = (double) (i_interval / i_compensation);
230
231     return (uint64_t)i_interval;
232 }
233
234 /*--------------------------------------------------------------------------
235  * rtcp_expire - decides to sent an RTCP report or a BYE record
236  *--------------------------------------------------------------------------
237  */
238 void rtcp_expire( vlc_object_t *p_this, rtcp_event_t rtcp_event, uint64_t u_bandwidth,
239                   uint32_t u_ssrc, vlc_bool_t b_sender, vlc_bool_t *b_first )
240 {
241     rtcp_t *p_rtcp = (rtcp_t *) p_this;
242     rtcp_client_t *p_client = NULL;
243     rtcp_stats_t *p_stats = NULL;
244     mtime_t i_interval = 0;
245     uint32_t i_pos = 0;
246
247     p_client = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
248     if( !p_client )
249         return;
250     p_stats = (rtcp_stats_t*) p_client->p_stats;
251     i_interval = (mtime_t) rtcp_interval( p_this, u_bandwidth,
252                                           u_ssrc, b_sender, *b_first );
253     p_rtcp->i_next_date = p_rtcp->i_last_date + i_interval;
254
255     switch( rtcp_event )
256     {
257         case EVENT_BYE:
258             if( p_rtcp->i_next_date <= p_rtcp->i_date )
259                 send_RTCP( p_this, rtcp_event );
260             else
261                 rtcp_schedule( p_this, p_rtcp->i_next_date, rtcp_event );
262             break;
263
264         case EVENT_REPORT:
265             if( p_rtcp->i_next_date <= p_rtcp->i_date )
266             {
267                 send_RTCP( p_this, rtcp_event );
268
269                 /* Magic numbers are from RFC 3550 page 92
270                  * 1.0/16.0 = 0.0625 and
271                  * 15.0/16.0 = 0.9375
272                  */
273                 p_stats->u_avg_pkt_size = (uint64_t)
274                       ( (double) ( (double)p_stats->u_sent_pkt_size / ((double)0.0625) ) +
275                       ( ((double)0.9357) * p_stats->u_avg_pkt_size ) );
276
277                 /* recalculate */
278                 p_rtcp->i_last_date = p_rtcp->i_date;
279                 i_interval = rtcp_interval( p_this, u_bandwidth,
280                                             u_ssrc, b_sender, *b_first );
281                 rtcp_schedule( p_this, p_rtcp->i_next_date + i_interval, rtcp_event );
282                 *b_first = VLC_FALSE;
283             }
284             else
285             {
286                 rtcp_schedule( p_this, p_rtcp->i_next_date, rtcp_event );
287             }
288             break;
289     }
290     p_rtcp->i_date = p_rtcp->i_next_date;
291 }
292
293 /*--------------------------------------------------------------------------
294  * Local functions prototoypes
295  *--------------------------------------------------------------------------
296  */
297 static int rtcp_decode_SR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
298 static int rtcp_decode_RR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
299 static int rtcp_decode_SR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
300 static int rtcp_decode_SDES( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
301 static int rtcp_decode_BYE( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
302 static int rtcp_decode_APP( vlc_object_t *p_this, rtcp_pkt_t *p_pkt );
303
304 /*--------------------------------------------------------------------------
305  * Local functions
306  *--------------------------------------------------------------------------
307  */
308 static int rtcp_decode_SR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
309 {
310     rtcp_t *p_rtcp = (rtcp_t *) p_this;
311     unsigned int i = 0;
312
313     if( !p_pkt )
314         return VLC_EGENERIC;
315
316     msg_Dbg( p_this, "decoding record: SR" );
317
318     /* parse sender info */
319         p_pkt->u_payload_type = RTCP_SR;
320     p_pkt->report.sr.ntp_timestampH = bs_read( p_rtcp->bs, 32 );
321     p_pkt->report.sr.ntp_timestampL = bs_read( p_rtcp->bs, 32 );
322     p_pkt->report.sr.rtp_timestamp  = bs_read( p_rtcp->bs, 32 );
323     p_pkt->report.sr.u_pkt_count    = bs_read( p_rtcp->bs, 32 ); /*sender*/
324     p_pkt->report.sr.u_octet_count  = bs_read( p_rtcp->bs, 32 ); /*sender*/
325
326     /* parse report block */
327     for( i=0; i < p_pkt->u_report; i++ )
328     {
329         rtcp_client_t *p_client = NULL;
330         uint32_t i_pos = 0;
331         uint32_t u_ssrc = 0;
332         int   result = 0;
333
334         u_ssrc = bs_read( p_rtcp->bs, 32 );
335
336         result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
337         if( result == VLC_EGENERIC )
338         {
339             result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
340             if( result == VLC_EGENERIC )
341                 return VLC_ENOMEM;
342         }
343         vlc_mutex_lock( &p_rtcp->object_lock );
344         p_client = p_rtcp->pp_clients[i_pos];
345
346         p_client->p_stats->u_SR_received++;
347         p_client->p_stats->u_pkt_count++;
348         p_client->p_stats->u_octet_count++;
349
350         msg_Dbg( p_this, "SR received %d, packet count %d, octect count %d, SSRC count %d",
351             p_client->p_stats->u_SR_received,
352             p_client->p_stats->u_pkt_count,
353             p_client->p_stats->u_octet_count,
354             p_pkt->u_ssrc );
355                 
356         p_client->p_stats->u_fraction_lost = bs_read( p_rtcp->bs, 8 );
357         p_client->p_stats->u_pkt_lost = bs_read( p_rtcp->bs, 24 );
358         p_client->p_stats->u_highest_seq_no = bs_read( p_rtcp->bs, 32 );
359         p_client->p_stats->u_jitter  = bs_read( p_rtcp->bs, 32 );
360         p_client->p_stats->u_last_SR = bs_read( p_rtcp->bs, 32 );
361         p_client->p_stats->u_delay_since_last_SR = (mtime_t) bs_read( p_rtcp->bs, 32 );
362
363         /* Magic numbers are from RFC 3550 page 92
364          * 1.0/16.0 = 0.0625 and
365          * 15.0/16.0 = 0.9375
366          */
367         p_client->p_stats->u_avg_pkt_size = (uint64_t)
368             ( (double)((double)p_client->p_stats->u_sent_pkt_size * (double)(0.0625)) +
369               ((double)(0.9375) * p_client->p_stats->u_avg_pkt_size) );
370
371         msg_Dbg( p_this, "fract lost %d, packet lost %d, highest seqno %d, "
372                          "jitter %d, last SR %d, delay %lld",
373             p_client->p_stats->u_fraction_lost,
374             p_client->p_stats->u_pkt_lost,
375             p_client->p_stats->u_highest_seq_no,
376             p_client->p_stats->u_jitter,
377             p_client->p_stats->u_last_SR,
378             p_client->p_stats->u_delay_since_last_SR );
379         p_client = NULL;
380         vlc_mutex_unlock( &p_rtcp->object_lock );
381     }
382     return VLC_SUCCESS;
383 }
384
385 static int rtcp_decode_RR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
386 {
387     rtcp_t *p_rtcp = (rtcp_t *) p_this;
388     unsigned int i = 0;
389
390     if( !p_pkt )
391         return VLC_EGENERIC;
392
393     msg_Dbg( p_this, "decoding record: RR" );
394
395     for( i=0; i < p_pkt->u_report; i++ )
396     {
397         rtcp_client_t *p_client = NULL;
398         uint32_t i_pos = 0;
399         uint32_t u_ssrc = 0;
400         int   result = 0;
401
402         u_ssrc = bs_read( p_rtcp->bs, 32 );
403
404         result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
405         if( result == VLC_EGENERIC )
406         {
407             result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
408             if( result == VLC_EGENERIC )
409                 return VLC_ENOMEM;
410         }
411
412         vlc_mutex_lock( &p_rtcp->object_lock );
413         p_client = p_rtcp->pp_clients[i_pos];
414
415         p_client->p_stats->u_RR_received++;
416         msg_Dbg( p_this, "RR received %d, SSRC %d", 
417                          p_client->p_stats->u_RR_received, u_ssrc );
418
419         p_client->p_stats->u_fraction_lost = bs_read( p_rtcp->bs, 8 );
420         p_client->p_stats->u_pkt_lost = bs_read( p_rtcp->bs, 24 );
421         p_client->p_stats->u_highest_seq_no = bs_read( p_rtcp->bs, 32 );
422         p_client->p_stats->u_jitter  = bs_read( p_rtcp->bs, 32 );
423         p_client->p_stats->u_last_SR = bs_read( p_rtcp->bs, 32 );
424         p_client->p_stats->u_delay_since_last_SR = (mtime_t) bs_read( p_rtcp->bs, 32 );
425
426         /* Magic numbers are from RFC 3550 page 92
427          * 1.0/16.0 = 0.0625 and
428          * 15.0/16.0 = 0.9375
429          */
430         p_client->p_stats->u_avg_pkt_size = (uint64_t)
431             ( (double)((double)p_client->p_stats->u_sent_pkt_size * (double)(0.0625)) +
432               ((double)(0.9375) * p_client->p_stats->u_avg_pkt_size) );
433
434         msg_Dbg( p_this, "fract lost %d, packet lost %d, highest seqno %d, "
435                          "jitter %d, last SR %d, delay %lld",
436             p_client->p_stats->u_fraction_lost,
437             p_client->p_stats->u_pkt_lost,
438             p_client->p_stats->u_highest_seq_no,
439             p_client->p_stats->u_jitter,
440             p_client->p_stats->u_last_SR,
441             p_client->p_stats->u_delay_since_last_SR );
442         p_client = NULL;
443         vlc_mutex_unlock( &p_rtcp->object_lock );
444     }
445     return VLC_SUCCESS;
446 }
447
448 static int rtcp_decode_SDES( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
449 {
450     rtcp_t *p_rtcp = (rtcp_t *) p_this;
451     unsigned int i = 0;
452
453     if( !p_pkt )
454         return VLC_EGENERIC;
455
456     msg_Dbg( p_this, "decoding record: SDES" );
457
458     for( i = 0; i < p_pkt->u_report; i++ )
459     {
460         rtcp_client_t *p_client = NULL;
461         uint32_t i_pos = 0;
462         uint32_t u_ssrc = 0;
463         uint8_t  u_item = 0;
464         uint8_t  u_length = 0;
465         int   i = 0;
466         int   result = 0;
467
468         u_ssrc = bs_read( p_rtcp->bs, 32 );
469
470         result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
471         if( result == VLC_EGENERIC )
472         {
473             result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
474             if( result == VLC_EGENERIC )
475                 return VLC_ENOMEM;
476         }
477
478         vlc_mutex_lock( &p_rtcp->object_lock );
479         p_client = p_rtcp->pp_clients[i_pos];
480
481         u_item = bs_read( p_rtcp->bs, 8 );
482         switch( u_item )
483         {
484             case RTCP_SDES_CNAME:
485             case RTCP_SDES_NAME:
486             case RTCP_SDES_EMAIL:
487             case RTCP_SDES_PHONE:
488             case RTCP_SDES_LOC:
489             case RTCP_SDES_TOOL:
490             case RTCP_SDES_NOTE:
491                         {
492                             char psz_name[255];
493
494                 u_length = bs_read( p_rtcp->bs, 8 );
495                 for( i = 0 ; i < u_length; i++ )
496                 {
497                     psz_name[i] = bs_read( p_rtcp->bs, 8 );
498                 }
499                 SDES_client_item_add( p_client, u_item, psz_name );
500                         }
501                         break;
502
503             case RTCP_SDES_PRIV: /* ignoring these */
504             {
505                 uint8_t u_prefix_len = 0;
506                                 uint8_t u_length = 0;
507                 char psz_prefix_name[255];
508                 char psz_name[255];
509
510                 u_length = bs_read( p_rtcp->bs, 8 );
511                 u_prefix_len = bs_read( p_rtcp->bs, 8 );
512                 if( u_prefix_len > 254 )
513                     u_prefix_len = 254;
514
515                 for( i=0 ; i < u_prefix_len; i++ )
516                 {
517                     psz_prefix_name[i] = bs_read( p_rtcp->bs, 8 );
518                 }
519                 psz_prefix_name[255] = '\0';
520                 SDES_client_item_add( p_client, u_item, psz_prefix_name );
521
522                 for( i=0 ; i < u_length; i++ )
523                 {
524                     psz_name[i] = bs_read( p_rtcp->bs, 8 );
525                 }
526                 psz_name[255] = '\0';
527                 SDES_client_item_add( p_client, u_item, psz_name );
528                         }
529                         break;
530
531             default:
532                 return VLC_EGENERIC;
533         }
534         /* Magic numbers are from RFC 3550 page 92
535          * 1.0/16.0 = 0.0625 and
536          * 15.0/16.0 = 0.9375
537          */
538         p_client->p_stats->u_avg_pkt_size = (uint64_t)
539             ( (double)((double)p_client->p_stats->u_sent_pkt_size * (double)(0.0625)) +
540               ((double)(0.9375) * p_client->p_stats->u_avg_pkt_size) );
541
542         p_client = NULL;
543         vlc_mutex_unlock( &p_rtcp->object_lock );
544     }
545     return VLC_SUCCESS;
546 }
547
548 static int rtcp_decode_BYE( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
549 {
550     rtcp_t    *p_rtcp = (rtcp_t *) p_this;
551     uint32_t  u_ssrc = 0;
552     uint8_t   u_length = 0;
553     int       i = 0;
554
555     if( !p_pkt )
556         return VLC_EGENERIC;
557
558     msg_Dbg( p_this, "decoding record: BYE" );
559
560     u_ssrc = bs_read( p_rtcp->bs, 32 );
561     p_rtcp->pf_del_client( p_this, u_ssrc );
562     u_length = p_pkt->u_length-1;
563     for( i = 0 ; i < u_length; i++ )
564     {
565         u_ssrc = bs_read( p_rtcp->bs, 8 );
566         p_rtcp->pf_del_client( p_this, u_ssrc );
567     }
568     return VLC_SUCCESS;
569 }
570
571 static int rtcp_decode_APP( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
572 {
573     rtcp_t        *p_rtcp = (rtcp_t *) p_this;
574         rtcp_client_t *p_client = NULL;
575     char  psz_name[4];
576     char* psz_data = NULL;
577         uint32_t u_ssrc = 0;
578     uint32_t i_pos = 0;
579     uint32_t i = 0;
580     int   result = 0;
581
582     if( !p_pkt )
583         return VLC_EGENERIC;
584
585     msg_Dbg( p_this, "decoding record: APP" );
586
587     u_ssrc = bs_read( p_rtcp->bs, 32 );
588
589     result = p_rtcp->pf_find_client( p_this, u_ssrc, &i_pos );
590     if( result == VLC_EGENERIC )
591     {
592         result = p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
593         if( result == VLC_EGENERIC )
594             return VLC_ENOMEM;
595     }
596
597     vlc_mutex_lock( &p_rtcp->object_lock );
598     p_client = p_rtcp->pp_clients[i_pos];
599
600     for( i = 0 ; i < 4; i++ )
601     {
602         psz_name[i] = bs_read( p_rtcp->bs, 8 );
603     }
604     psz_name[4] = '\0';
605         
606     p_pkt->u_payload_type = RTCP_APP;
607     p_pkt->report.app.psz_prefix = strdup( psz_name );
608     p_pkt->report.app.u_prefix_len = 4;
609     p_pkt->u_length -= 4;
610
611     psz_data = (char *) malloc( p_pkt->u_length );
612     if( !psz_data ) {
613         vlc_mutex_unlock( &p_rtcp->object_lock );
614         return VLC_EGENERIC;
615     }
616
617     for( i = 0; i < p_pkt->u_length; i-- )
618     {
619         psz_data[i] = bs_read( p_rtcp->bs, 8 );
620     }
621     psz_data[p_pkt->u_length] = '\0';
622
623     p_pkt->report.app.psz_data = strdup( psz_data );
624     p_pkt->report.app.u_length = p_pkt->u_length;
625
626     p_client = NULL;
627     vlc_mutex_unlock( &p_rtcp->object_lock );
628
629     /* Just ignore this packet */
630     return VLC_SUCCESS;
631 }
632
633 /* Decode RTCP packet
634  * Decode incoming RTCP packet and inspect the records types.
635  */
636 int rtcp_pkt_decode( vlc_object_t *p_this, rtcp_pkt_t *p_pkt, block_t *p_block )
637 {
638     rtcp_t *p_rtcp = (rtcp_t *) p_this;
639
640     if( !p_pkt && !p_block )
641         return VLC_EGENERIC;
642
643     bs_init( p_rtcp->bs, p_block->p_buffer, p_block->i_buffer );
644
645     p_pkt->u_version = bs_read( p_rtcp->bs, 2 );
646     p_pkt->b_padding = bs_read( p_rtcp->bs, 1 ) ? VLC_TRUE : VLC_FALSE;
647     p_pkt->u_report  = bs_read( p_rtcp->bs, 5 );
648     p_pkt->u_payload_type = bs_read( p_rtcp->bs, 8 );
649     p_pkt->u_length = bs_read( p_rtcp->bs, 16 );
650
651     if( p_pkt->u_payload_type != RTCP_SDES )
652         p_pkt->u_ssrc = bs_read( p_rtcp->bs, 32 );
653
654     msg_Dbg( p_this, "New RTCP packet: version %d, padding %s, count %d, "
655                      "type %d, length %d, SSRC %d",
656         p_pkt->u_version,
657         p_pkt->b_padding ? "true" : "false",
658         p_pkt->u_report,
659         p_pkt->u_payload_type,
660         p_pkt->u_length,
661         p_pkt->u_ssrc );
662
663     while( !bs_eof( p_rtcp->bs ) )
664     {
665                 uint32_t i_pos = 0;
666                 
667         switch( p_pkt->u_payload_type )
668         {
669             case RTCP_SR:
670                 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
671                     p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
672                 rtcp_decode_SR( p_this, p_pkt );
673                 break;
674
675             case RTCP_RR:
676                 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
677                     p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
678                 rtcp_decode_RR( p_this, p_pkt );
679                 break;
680
681             case RTCP_SDES:
682                 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
683                     p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
684                 rtcp_decode_SDES( p_this, p_pkt );
685                 break;
686
687             case RTCP_BYE:
688                 rtcp_decode_BYE( p_this, p_pkt );
689 #if 0
690                  if( p_rtcp->pf_find_sender( p_this, pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
691                      p_rtcp->pf_del_sender( p_this, p_pkt->u_ssrc );
692 #endif
693                 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
694                     p_rtcp->pf_del_client( p_this, p_pkt->u_ssrc );
695
696                 if( p_rtcp->u_active < p_rtcp->u_members )
697                 {
698                                         rtcp_event_t event = EVENT_BYE;
699                                         
700                     p_rtcp->i_next_date = p_rtcp->i_date +
701                                 (mtime_t) ( (p_rtcp->u_active / p_rtcp->u_members) *
702                                             (p_rtcp->i_next_date - p_rtcp->i_date) );
703                     p_rtcp->i_last_date = p_rtcp->i_date -
704                                         (mtime_t)
705                                             ( (mtime_t)(p_rtcp->u_active / p_rtcp->u_members) *
706                                               (p_rtcp->i_date - p_rtcp->i_last_date) );
707                     /* schedule for next period */
708                     rtcp_schedule( VLC_OBJECT(p_rtcp), p_rtcp->i_next_date, event );
709                     p_rtcp->u_members = p_rtcp->u_active;
710                 }
711                 else p_rtcp->u_members++;
712                 break;
713
714             case RTCP_APP:
715                 if( p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos ) == VLC_EGENERIC )
716                     p_rtcp->pf_add_client( p_this, p_pkt->u_ssrc, &i_pos );
717                 rtcp_decode_APP( p_this, p_pkt );
718                 break;
719
720             default:
721                 return VLC_EGENERIC;
722         }
723     }
724     return VLC_SUCCESS;
725 }
726
727 /*
728  * Create RTCP records for reporting to server.
729  */
730 rtcp_pkt_t *rtcp_pkt_new( vlc_object_t *p_this, int type )
731 {
732     rtcp_pkt_t *p_pkt = NULL;
733
734     p_pkt = (rtcp_pkt_t *) malloc( sizeof( rtcp_pkt_t ) );
735     if( !p_pkt )
736         return NULL;
737
738     memset( p_pkt, 0 , sizeof( rtcp_pkt_t ) );
739     p_pkt->u_version = 2;
740     p_pkt->u_payload_type = type;
741     p_pkt->u_length = RTCP_HEADER_LEN;
742
743     switch( type )
744     {
745         case RTCP_SR:
746             p_pkt->u_length += sizeof(rtcp_SR_t);
747             break;
748         case RTCP_RR:
749             p_pkt->u_length += sizeof(rtcp_RR_t);
750             break;
751         case RTCP_SDES:
752             p_pkt->u_length += sizeof(rtcp_SDES_t);
753                         if( p_pkt->report.sdes.pp_items )
754                                 p_pkt->u_length += p_pkt->report.sdes.u_items;
755             break;
756         case RTCP_BYE:
757             p_pkt->u_length += sizeof(rtcp_BYE_t);
758             break;
759         case RTCP_APP:
760             p_pkt->u_length += sizeof(rtcp_APP_t);
761             break;
762         default:
763             free(p_pkt);
764             return NULL;
765     }
766     return p_pkt;
767 }
768
769 void rtcp_pkt_del( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
770 {
771     if( !p_pkt )
772         return;
773
774     switch( p_pkt->u_payload_type )
775     {
776         case RTCP_SR:
777         case RTCP_RR:
778             break;
779         case RTCP_SDES:
780             if( p_pkt->report.sdes.pp_items )
781             {
782                 uint32_t i = 0;
783
784                 for( i = 0; i < p_pkt->report.sdes.u_items; i++ )
785                 {
786                     rtcp_SDES_item_t *p_old =
787                         p_pkt->report.sdes.pp_items[i];
788                     REMOVE_ELEM( p_pkt->report.sdes.pp_items,
789                                  p_pkt->report.sdes.u_items, i );
790                     p_pkt->report.sdes.u_items--;
791                     if( p_old->psz_data )
792                         free( p_old->psz_data );
793                     free( p_old );
794                 }
795             }
796             break;
797         case RTCP_BYE:
798             break;
799         case RTCP_APP:
800             if( p_pkt->report.app.psz_prefix )
801                 free( p_pkt->report.app.psz_prefix );
802             if( p_pkt->report.app.psz_data )
803                 free( p_pkt->report.app.psz_data );
804             break;
805         default:
806             msg_Err( p_this, "unknown RTCP packet type %d: "
807                              "possible leaking of memory.",
808                                                         p_pkt->u_payload_type );
809             break;
810     }
811     free( p_pkt );
812 }
813
814 block_t *rtcp_encode_SR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
815 {
816     rtcp_t *p_rtcp = (rtcp_t *) p_this;
817     mtime_t ntp_time;
818     bs_t bits, *s = &bits;
819     block_t *p_block = NULL;
820     rtcp_stats_t *p_stats = NULL;
821     rtcp_client_t *p_client = NULL;
822     uint32_t i_pos = 0;
823         int result = 0;
824
825     if( p_pkt->u_payload_type != RTCP_SR )
826         return NULL;
827
828     /* FIXME: Maybe this should be a buffer pool instead */
829     p_block = block_New( p_this, p_pkt->u_length );
830     if( !p_block )
831         return NULL;
832
833     bs_init( s, p_block->p_buffer, p_block->i_buffer );
834
835     /* Fill in header */
836     bs_write( s, 2, p_pkt->u_version );
837     bs_write( s, 1, 0 ); /* padding */
838     bs_write( s, 5, p_pkt->u_report );
839     bs_write( s, 8, p_pkt->u_payload_type );
840     bs_write( s, 16, p_pkt->u_length );
841     bs_write( s, 32, p_pkt->u_ssrc );
842
843     /* sender info */
844     ntp_time = mdate();
845     bs_write( s, 32, ((unsigned int)(ntp_time>>32)) ); /* ntp_timestampH */
846     bs_write( s, 32, ((unsigned int)ntp_time) );/* ntp_timestampL */
847
848     /* FIXME: Make sure to generate a good RTP server timestamp.
849         p_pkt->report.sr.rtp_timestamp = htonl(
850         (unsigned int) ((double)ntp_time.tv_sec +
851         (double)ntp_time.tv_usec/1000000.) * p_mux->rate
852         + session->start_rtptime ); */
853     bs_write( s, 32, p_pkt->report.sr.rtp_timestamp );
854     bs_write( s, 32, p_pkt->report.sr.u_pkt_count );
855     bs_write( s, 32, p_pkt->report.sr.u_octet_count );
856
857     /* report block */
858     result = p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos );
859     if( result == VLC_EGENERIC )
860     {
861         msg_Err( p_this, "SR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
862         free( p_block );
863         return NULL;
864     }
865
866     vlc_mutex_lock( &p_rtcp->object_lock );
867     p_client = p_rtcp->pp_clients[i_pos];
868
869     p_stats = p_client->p_stats;
870     if( !p_stats ) {
871         msg_Err( p_this, "SR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
872         free( p_block );
873         return NULL;
874     }
875     bs_write( s, 32, p_stats->l_dest_SSRC );
876     bs_write( s,  8, p_stats->u_fraction_lost );
877     bs_write( s, 24, p_stats->u_pkt_lost );
878     bs_write( s, 32, p_stats->u_highest_seq_no );
879     bs_write( s, 32, p_stats->u_jitter );
880     bs_write( s, 32, p_stats->u_last_SR );
881     bs_write( s, 32, p_stats->u_delay_since_last_SR );
882
883     p_client = NULL;
884     vlc_mutex_unlock( &p_rtcp->object_lock );
885
886     /* possible SR extension */
887     return p_block;
888 }
889
890 block_t *rtcp_encode_RR( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
891 {
892     rtcp_t *p_rtcp = (rtcp_t *) p_this;
893     bs_t bits, *s = &bits;
894     block_t *p_block = NULL;
895     rtcp_stats_t *p_stats = NULL;
896     rtcp_client_t *p_client = NULL;
897         uint32_t i_pos = 0;
898         int result = 0;
899
900     if( p_pkt->u_payload_type != RTCP_RR )
901         return NULL;
902
903     /* FIXME: Maybe this should be a buffer pool instead */
904     p_block = block_New( p_this, p_pkt->u_length );
905     if( !p_block )
906         return NULL;
907
908     bs_init( s, p_block->p_buffer, p_block->i_buffer );
909
910     /* Fill in header */
911     bs_write( s, 2, p_pkt->u_version );
912     bs_write( s, 1, 0 ); /* padding */
913     bs_write( s, 5, p_pkt->u_report );
914     bs_write( s, 8, p_pkt->u_payload_type );
915     bs_write( s, 16, p_pkt->u_length );
916     bs_write( s, 32, p_pkt->u_ssrc );
917
918     /* report block */
919     result = p_rtcp->pf_find_client( p_this, p_pkt->u_ssrc, &i_pos );
920     if( result == VLC_EGENERIC )
921     {
922         msg_Err( p_this, "RR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
923         free( p_block );
924         return NULL;
925     }
926
927     vlc_mutex_lock( &p_rtcp->object_lock );
928     p_client = p_rtcp->pp_clients[i_pos];
929
930     p_stats = p_client->p_stats;
931     if( !p_stats ) {
932         msg_Err( p_this, "RR: SSRC identifier doesn't exists", p_pkt->u_ssrc );
933         free( p_block );
934         return NULL;
935     }
936     bs_write( s, 32, p_stats->l_dest_SSRC );
937     bs_write( s,  8, p_stats->u_fraction_lost );
938     bs_write( s, 24, p_stats->u_pkt_lost );
939     bs_write( s, 32, p_stats->u_highest_seq_no );
940     bs_write( s, 32, p_stats->u_jitter );
941     bs_write( s, 32, p_stats->u_last_RR );
942     bs_write( s, 32, p_stats->u_delay_since_last_RR );
943
944     p_client = NULL;
945     vlc_mutex_unlock( &p_rtcp->object_lock );
946
947     /* possible RR extension */
948     return p_block;
949 }
950
951 block_t *rtcp_encode_SDES( vlc_object_t *p_this, rtcp_pkt_t *p_pkt )
952 {
953     bs_t bits, *s = &bits;
954     block_t *p_block = NULL;
955     uint32_t i_chunks;
956
957     if( p_pkt->u_payload_type != RTCP_SDES )
958         return NULL;
959
960     /* FIXME: Maybe this should be a buffer pool instead */
961     p_block = block_New( p_this, p_pkt->u_length );
962     if( !p_block )
963         return NULL;
964
965     bs_init( s, p_block->p_buffer, p_block->i_buffer );
966
967     /* Fill in header */
968     bs_write( s, 2, p_pkt->u_version );
969     bs_write( s, 1, 0 ); /* padding */
970     bs_write( s, 5, p_pkt->u_report ); /* Number of SSRC/CSRC chunks */
971     bs_write( s, 8, p_pkt->u_payload_type );
972     bs_write( s, 16, p_pkt->u_length );
973     bs_write( s, 32, p_pkt->u_ssrc );
974
975     /* fill in record */
976     for( i_chunks = 0; i_chunks < p_pkt->u_report; i_chunks++ )
977     {
978         uint32_t i_item;
979
980         for( i_item = 0 ; i_item < p_pkt->report.sdes.u_items; i_item++ )
981         {
982             uint32_t i_count = strlen( p_pkt->report.sdes.pp_items[i_item]->psz_data );
983             uint8_t  u_octet = i_count / 8;  /* Octect count ??*/
984             rtcp_SDES_item_t *p_item = p_pkt->report.sdes.pp_items[i_item];
985                         uint32_t i_pos, i_pad, i_padding;
986
987             bs_write( s, 8, p_item->u_type );
988             bs_write( s, 8, u_octet );
989
990             for( i_pos = 0; i_pos < i_count; i_pos++ )
991             {
992                 /* FIXME: must be UTF 8 encoded */
993                 bs_write( s, 8, p_item->psz_data[i_pos] );
994             }
995
996             /* do we need padding to 32 bit boundary? */
997             i_padding = 0;
998             if( ((i_count + 2) % 4) != 0 )
999                 i_padding = (i_count + 2) - (((i_count + 2) % 4) << 2);
1000             for( i_pad = 0; i_pad < i_padding; i_pad++ )
1001             {
1002                 bs_write( s, 8, 0 );
1003             }
1004         }
1005     }
1006     return p_block;
1007 }
1008
1009 block_t *rtcp_encode_BYE( vlc_object_t *p_this, rtcp_pkt_t *p_pkt, char *psz_reason )
1010 {
1011     bs_t bits, *s = &bits;
1012     block_t *p_block = NULL;
1013     uint32_t i_count = strlen( psz_reason );
1014     uint8_t  u_octet = i_count / 8;  /* Octect count ??*/
1015     int32_t i_pos, i_pad, i_padding;
1016
1017     if( p_pkt->u_payload_type != RTCP_BYE )
1018         return NULL;
1019
1020     /* FIXME: Maybe this should be a buffer pool instead */
1021     p_block = block_New( p_this, p_pkt->u_length );
1022     if( !p_block )
1023         return NULL;
1024
1025     bs_init( s, p_block->p_buffer, p_block->i_buffer );
1026
1027     /* Fill in header */
1028     bs_write( s, 2, p_pkt->u_version );
1029     bs_write( s, 1, 0 ); /* padding */
1030     bs_write( s, 5, p_pkt->u_report ); /* Number of SSRC/CSRC chunks */
1031     bs_write( s, 8, p_pkt->u_payload_type );
1032     bs_write( s, 16, p_pkt->u_length );
1033     bs_write( s, 32, p_pkt->u_ssrc );
1034
1035     /* Give reason for leaving */
1036     //FIXME: bs_write( s, 8, p_item->u_type );
1037     bs_write( s, 8, u_octet );
1038         
1039     for( i_pos = 0; i_pos < i_count; i_pos++ )
1040     {
1041         /* FIXME: must be UTF 8 encoded */
1042         bs_write( s, 8, psz_reason[i_pos] );
1043     }
1044
1045     /* do we need padding to 32 bit boundary? */
1046     i_padding = 0;
1047     if( ((i_count + 2) % 4) != 0 )
1048         i_padding = (i_count + 2) - (((i_count + 2) % 4) << 2);
1049     for( i_pad = 0; i_pad < i_padding; i_pad++ )
1050     {
1051         bs_write( s, 8, 0 );
1052     }
1053     return p_block;
1054 }