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