00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00027 #include "rtp.h"
00028 #include "rtpptdefs.h"
00029 #include "bufferpool.h"
00030
00039 static int rtp_hdr_val_chk(rtp_pkt * pkt, int len)
00040 {
00041 if (RTP_PAYLOAD_SIZE(pkt, len) < 0) {
00042
00043 nms_printf(NMSML_ERR,
00044 "RTP packet too small (%d: smaller than RTP header size)!!!\n",
00045 len);
00046 return 1;
00047 }
00048
00049 if (pkt->ver != RTP_VERSION) {
00050 nms_printf(NMSML_WARN,
00051 "RTP Header not valid: mismatching version number!"
00052 BLANK_LINE);
00053 return 1;
00054 }
00055 if ((pkt->pt >= 200) && (pkt->pt <= 204)) {
00056 nms_printf(NMSML_WARN,
00057 "RTP Header not valid: mismatching payload type!"
00058 BLANK_LINE);
00059 return 1;
00060 }
00061 if ((pkt->pad)
00062 && (*(((uint8_t *) pkt) + len - 1) >
00063 (len - ((uint8_t *) (pkt->data) - (uint8_t *) pkt)))) {
00064 nms_printf(NMSML_WARN,
00065 "RTP Header not valid: mismatching lenght!"
00066 BLANK_LINE);
00067 return 1;
00068 }
00069 if ((pkt->cc)
00070 && (pkt->cc >
00071 (len - ((uint8_t *) (pkt->data) - (uint8_t *) pkt)) -
00072 ((*(((uint8_t *) pkt) + len - 1)) * pkt->pad))) {
00073 nms_printf(NMSML_WARN,
00074 "RTP Header not valid: mismatching CSRC count!"
00075 BLANK_LINE);
00076 return 1;
00077 }
00078
00079 return 0;
00080 }
00081
00090 static void rtp_init_seq(rtp_ssrc * stm_src, uint16_t seq)
00091 {
00092 struct rtp_ssrc_stats *stats = &(stm_src->ssrc_stats);
00093
00094 stats->base_seq = seq - 1;
00095 stats->max_seq = seq;
00096 stats->bad_seq = RTP_SEQ_MOD + 1;
00097 stats->cycles = 0;
00098 stats->received = 0;
00099 stats->received_prior = 0;
00100 stats->expected_prior = 1;
00101
00102
00103
00104 stm_src->next_active = stm_src->rtp_sess->active_ssrc_queue;
00105 stm_src->rtp_sess->active_ssrc_queue = stm_src;
00106
00107 return;
00108 }
00109
00119 void rtp_update_seq(rtp_ssrc * stm_src, uint16_t seq)
00120 {
00121 struct rtp_ssrc_stats *stats = &(stm_src->ssrc_stats);
00122 uint16_t udelta = seq - stats->max_seq;
00123
00124 if (stats->probation) {
00125 if (seq == stats->max_seq + 1) {
00126 stats->probation--;
00127 stats->max_seq = seq;
00128 if (stats->probation == 0) {
00129 rtp_init_seq(stm_src, seq);
00130 stats->received++;
00131 return;
00132 }
00133 } else {
00134 stats->probation = MIN_SEQUENTIAL - 1;
00135 stats->max_seq = seq;
00136 }
00137 return;
00138 } else if (udelta < MAX_DROPOUT) {
00139 if (seq < stats->max_seq) {
00140
00141
00142
00143 stats->cycles += RTP_SEQ_MOD;
00144 }
00145 stats->max_seq = seq;
00146 } else if (udelta <= RTP_SEQ_MOD - MAX_MISORDER) {
00147
00148 if (seq == stats->bad_seq) {
00149 rtp_init_seq(stm_src, seq);
00150 } else {
00151 stats->bad_seq = (seq + 1) & (RTP_SEQ_MOD - 1);
00152 return;
00153 }
00154 }
00155
00156
00157 stats->received++;
00158 return;
00159 }
00160
00170 int rtp_recv(rtp_session * rtp_sess)
00171 {
00172
00173 int n;
00174 unsigned rate;
00175 int slot;
00176 rtp_pkt *pkt;
00177 rtp_ssrc *stm_src;
00178 struct timeval now;
00179 unsigned transit;
00180 int delta;
00181
00182 struct sockaddr_storage serveraddr;
00183 nms_sockaddr server =
00184 { (struct sockaddr *) &serveraddr, sizeof(serveraddr) };
00185
00186 if ((slot = bpget(rtp_sess->bp)) < 0) {
00187 nms_printf(NMSML_VERB,
00188 "No more space in Playout Buffer!" BLANK_LINE);
00189 return 1;
00190 }
00191
00192 if ((n = recvfrom(rtp_sess->transport.RTP.sock.fd,
00193 &(rtp_sess->bp->bufferpool[slot]),
00194 BP_SLOT_SIZE, 0, server.addr, &server.addr_len)) == -1) {
00195 switch (errno) {
00196 case EBADF:
00197 nms_printf(NMSML_ERR,
00198 "RTP recvfrom: invalid descriptor\n");
00199 break;
00200 #ifndef WIN32
00201 case ENOTSOCK:
00202 nms_printf(NMSML_ERR, "RTP recvfrom: not a socket\n");
00203 break;
00204 #endif
00205 case EINTR:
00206 nms_printf(NMSML_ERR,
00207 "RTP recvfrom: The receive was interrupted by delivery"
00208 " of a signal\n");
00209 break;
00210 case EFAULT:
00211 nms_printf(NMSML_ERR,
00212 "RTP recvfrom: The buffer points outside userspace\n");
00213 break;
00214 case EINVAL:
00215 nms_printf(NMSML_ERR,
00216 "RTP recvfrom: Invalid argument passed.\n");
00217 break;
00218 default:
00219 nms_printf(NMSML_ERR, "in RTP recvfrom\n");
00220 break;
00221 }
00222 return 1;
00223 }
00224 gettimeofday(&now, NULL);
00225
00226 pkt = (rtp_pkt *)(&rtp_sess->bp->bufferpool[slot]);
00227
00228 if (rtp_hdr_val_chk(pkt, n)) {
00229 nms_printf(NMSML_NORM, "RTP header validity check FAILED!\n");
00230 bpfree(rtp_sess->bp, slot);
00231 return 0;
00232 }
00233
00234 switch (rtp_ssrc_check (rtp_sess, RTP_PKT_SSRC(pkt),
00235 &stm_src, &server, RTP)) {
00236 case SSRC_KNOWN:
00237 if (stm_src->done_seek) {
00238 stm_src->ssrc_stats.probation = 0;
00239 stm_src->ssrc_stats.max_seq = RTP_PKT_SEQ(pkt);
00240 stm_src->ssrc_stats.firstts = RTP_PKT_TS(pkt);
00241 stm_src->ssrc_stats.lastts = RTP_PKT_TS(pkt);
00242 stm_src->ssrc_stats.firsttv = now;
00243 stm_src->ssrc_stats.jitter = 0;
00244
00245 stm_src->ssrc_stats.base_seq = RTP_PKT_SEQ(pkt) - 1;
00246 stm_src->ssrc_stats.bad_seq = RTP_SEQ_MOD + 1;
00247 stm_src->ssrc_stats.cycles = 0;
00248 stm_src->ssrc_stats.received = 0;
00249 stm_src->ssrc_stats.received_prior = 0;
00250 stm_src->ssrc_stats.expected_prior = 1;
00251 }
00252
00253 rtp_update_seq(stm_src, RTP_PKT_SEQ(pkt));
00254 rtp_update_fps(stm_src, RTP_PKT_TS(pkt), RTP_PKT_PT(pkt));
00255
00256 if (!rtp_sess->ptdefs[pkt->pt]
00257 || !(rate = (rtp_sess->ptdefs[pkt->pt]->rate)))
00258 rate = RTP_DEF_CLK_RATE;
00259
00260 transit = (uint32_t) (((double) now.tv_sec +
00261 (double) now.tv_usec / 1000000.0) *
00262 (double) rate) - ntohl(pkt->time);
00263 delta = transit - stm_src->ssrc_stats.transit;
00264 stm_src->ssrc_stats.transit = transit;
00265
00266 if (stm_src->done_seek) {
00267 nms_printf(NMSML_NORM, "Seek reset performed on %u\n", stm_src->ssrc_stats.firstts);
00268 stm_src->done_seek = 0;
00269 }
00270 else {
00271 if (delta < 0)
00272 delta = -delta;
00273 stm_src->ssrc_stats.jitter +=
00274 (1. / 16.) * ((double) delta - stm_src->ssrc_stats.jitter);
00275 }
00276 break;
00277 case SSRC_NEW:
00278 rtp_sess->sess_stats.senders++;
00279 rtp_sess->sess_stats.members++;
00280 case SSRC_RTPNEW:
00281 stm_src->ssrc_stats.probation = MIN_SEQUENTIAL;
00282 stm_src->ssrc_stats.max_seq = RTP_PKT_SEQ(pkt) - 1;
00283
00284 if (!rtp_sess->ptdefs[pkt->pt]
00285 || !(rate = (rtp_sess->ptdefs[pkt->pt]->rate)))
00286 rate = RTP_DEF_CLK_RATE;
00287 (stm_src->ssrc_stats).transit =
00288 (uint32_t) (((double) now.tv_sec +
00289 (double) now.tv_usec / 1000000.0) *
00290 (double) rate) - ntohl(pkt->time);
00291
00292 (stm_src->ssrc_stats).jitter = 0;
00293 (stm_src->ssrc_stats).firstts = RTP_PKT_TS(pkt);
00294 stm_src->ssrc_stats.lastts = RTP_PKT_TS(pkt);
00295 (stm_src->ssrc_stats).firsttv = now;
00296
00297 rtp_update_seq(stm_src, RTP_PKT_SEQ(pkt));
00298 rtp_update_fps(stm_src, RTP_PKT_TS(pkt), RTP_PKT_PT(pkt));
00299 break;
00300 case SSRC_COLLISION:
00301 bprmv(rtp_sess->bp, stm_src->po, slot);
00302 return 0;
00303 break;
00304 case -1:
00305 return 1;
00306 break;
00307 default:
00308 break;
00309 }
00310
00311 switch (poadd(stm_src->po, slot, stm_src->ssrc_stats.cycles)) {
00312 case PKT_DUPLICATED:
00313 nms_printf(NMSML_VERB,
00314 "WARNING: Duplicate packet found... discarded\n");
00315 bpfree(rtp_sess->bp, slot);
00316 return 0;
00317 break;
00318 case PKT_MISORDERED:
00319 nms_printf(NMSML_VERB,
00320 "WARNING: Misordered packet found... reordered\n");
00321 break;
00322 default:
00323 break;
00324 }
00325
00326 stm_src->po->pobuff[slot].pktlen = n;
00327
00328 return 0;
00329 }