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