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