00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028 #include "rtcp.h"
00029 #include "utils.h"
00030
00037 static void rtcp_clean(void *args)
00038 {
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
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
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
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