rtcp.c

Go to the documentation of this file.
00001 /* * 
00002  * This file is part of libnemesi
00003  *
00004  * Copyright (C) 2007 by LScube team <team@streaming.polito.it>
00005  * See AUTHORS for more details
00006  * 
00007  * libnemesi is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * libnemesi is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with libnemesi; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  *  
00021  * */
00022 
00028 #include "rtcp.h"
00029 #include "utils.h"
00030 
00037 static void rtcp_clean(void *args)
00038 {
00039     /*
00040     rtp_session *rtp_sess_head = (*(rtp_session **) args);
00041     rtp_session *rtp_sess;
00042     rtp_ssrc *stm_src;
00043 
00044     for (rtp_sess = rtp_sess_head; rtp_sess; rtp_sess = rtp_sess->next)
00045         for (stm_src = rtp_sess->ssrc_queue; stm_src;
00046              stm_src = stm_src->next)
00047             if (stm_src->rtcptofd > 0)
00048                 close(stm_src->rtcptofd);
00049     */
00050     nms_printf(NMSML_DBG1, "RTCP Thread R.I.P.\n");
00051 }
00052 
00053 double rtcp_interval(int members, int senders,
00054                      double bw, int sent,
00055                      double avg_rtcp_size, int initial);
00056 
00063 static void *rtcp(void *args)
00064 {
00065     rtp_session *rtp_sess_head = ((rtp_thread *) args)->rtp_sess_head;
00066     rtp_session *rtp_sess;
00067     struct rtcp_event *head = NULL;
00068     int maxfd = 0, ret;
00069     double t;
00070     struct timeval tv, now;
00071 
00072     fd_set readset;
00073 
00074     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
00075     // pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
00076     pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
00077     pthread_cleanup_push(rtcp_clean, (void *) &rtp_sess_head);
00078     pthread_cleanup_push(rtcp_clean_events, (void *) &head);
00079 
00080     for (rtp_sess = rtp_sess_head; rtp_sess; rtp_sess = rtp_sess->next) {
00081         t = rtcp_interval(rtp_sess->sess_stats.members,
00082                   rtp_sess->sess_stats.senders,
00083                   rtp_sess->sess_stats.rtcp_bw,
00084                   rtp_sess->sess_stats.we_sent,
00085                   rtp_sess->sess_stats.avg_rtcp_size,
00086                   rtp_sess->sess_stats.initial);
00087 
00088         tv.tv_sec = (long int) t;
00089         tv.tv_usec = (long int) ((t - tv.tv_sec) * 1000000);
00090         gettimeofday(&now, NULL);
00091         nms_timeval_add(&(rtp_sess->sess_stats.tn), &now, &tv);
00092 
00093         if ((head =
00094              rtcp_schedule(head, rtp_sess, rtp_sess->sess_stats.tn,
00095                    RTCP_RR)) == NULL)
00096             pthread_exit(NULL);
00097         nms_printf(NMSML_DBG1, "RTCP: %d.%d -> %d.%d\n", now.tv_sec,
00098                now.tv_usec, head->tv.tv_sec, head->tv.tv_usec);
00099     }
00100 
00101     while (1) {
00102 
00103         pthread_testcancel();
00104 
00105         FD_ZERO(&readset);
00106 
00107         for (rtp_sess = rtp_sess_head; rtp_sess;
00108              rtp_sess = rtp_sess->next) {
00109             maxfd = max(rtp_sess->transport.RTCP.sock.fd, maxfd);
00110             FD_SET(rtp_sess->transport.RTCP.sock.fd, &readset);
00111         }
00112 
00113         gettimeofday(&now, NULL);
00114         if (nms_timeval_subtract(&tv, &(head->tv), &now)) {
00115             tv.tv_sec = 0;
00116             tv.tv_usec = 0;
00117         }
00118         nms_printf(NMSML_DBG3,
00119                "RTCP: now: %d.%d -> head:%d.%d - sleep: %d.%d\n",
00120                now.tv_sec, now.tv_usec, head->tv.tv_sec,
00121                head->tv.tv_usec, tv.tv_sec, tv.tv_usec);
00122 
00123         if (select(maxfd + 1, &readset, NULL, NULL, &tv) == 0) {
00124             /* timer scaduto */
00125             if ((head = rtcp_handle_event(head)) == NULL)
00126                 pthread_exit(NULL);
00127         }
00128 
00129         for (rtp_sess = rtp_sess_head; rtp_sess;
00130              rtp_sess = rtp_sess->next)
00131             if (FD_ISSET(rtp_sess->transport.RTCP.sock.fd, &readset)) {
00132                 if ((ret = rtcp_recv(rtp_sess)) < 0)
00133                     pthread_exit(NULL);
00134             }
00135     }
00136 
00137     pthread_cleanup_pop(1);
00138     pthread_cleanup_pop(1);
00139 }
00140 
00148 int rtcp_thread_create(rtp_thread * rtp_th)
00149 {
00150     int n;
00151     pthread_attr_t rtcp_attr;
00152 
00153     pthread_attr_init(&rtcp_attr);
00154     if (pthread_attr_setdetachstate(&rtcp_attr, PTHREAD_CREATE_JOINABLE) !=
00155         0)
00156         return nms_printf(NMSML_FATAL,
00157                   "Cannot set RTCP Thread attributes!\n");
00158 
00159     if ((n =
00160          pthread_create(&rtp_th->rtcp_tid, &rtcp_attr, &rtcp,
00161                 (void *) rtp_th)) > 0)
00162         return nms_printf(NMSML_FATAL, "%s\n", strerror(n));
00163 
00164     return 0;
00165 }
00166 

Generated on Tue Feb 3 03:10:02 2009 for libnemesi by  doxygen 1.5.4