Changeset 4260
- Timestamp:
- 08/11/08 19:12:03 (5 years ago)
- Location:
- vic/branches/cc/rtp
- Files:
-
- 3 modified
Legend:
- Unmodified
- Added
- Removed
-
vic/branches/cc/rtp/rtp.h
r4259 r4260 137 137 #define XR_BT_3 0x03 // Packet Receipt Times Report Block 138 138 #define XR_BT_4 0x04 // Receiver Reference Time Report Block 139 struct rtcp_xr_hdr { 139 struct rtcp_xr { 140 // extended report block header 140 141 u_int16_t xr_flags; /* BT:8 TS:8 */ 141 142 u_int16_t xr_len; /* XR report block length (in bytes)*/ 142 }; 143 144 struct rtcp_xr_blk { 143 144 // extended report block contents 145 145 u_int32_t ssrc; /* ssrc of the RTP data pkt being reported upon by this */ 146 146 u_int16_t begin_seq; /* first seqno that this block report */ -
vic/branches/cc/rtp/session.cpp
r4259 r4260 488 488 // RTCP XR (Loss RLE Report Block) 489 489 // (it is XR_BT_1 defined in rtp/rtp.h) 490 send_xreport(ch, 1);490 send_xreport(ch, XR_BT_1, 0); 491 491 } 492 492 … … 495 495 // RTCP XR (Packet Receipt Times Report Block) 496 496 // (it is XR_BT_3 defined in rtp/rtp.h) 497 send_xreport(ch, 3);497 send_xreport(ch, XR_BT_3, 0); 498 498 } 499 499 … … 626 626 { 627 627 send_report(ch, 0); 628 //send_xreport(ch, 0); // this XR report will be driven by timer629 628 } 630 629 … … 632 631 * Send an RTP extended report packet. 633 632 */ 634 void SessionManager::send_xreport(CtrlHandler* ch, int bye, int app) 635 { 636 UNUSED(app); 637 int bt = bye; // XR block type 633 void SessionManager::send_xreport(CtrlHandler* ch, int bt, int bye) 634 { 635 UNUSED(bye); 638 636 639 637 SourceManager& sm = SourceManager::instance(); … … 642 640 rh->rh_ssrc = s.srcid(); 643 641 int flags = RTP_VERSION << 14; // RTCP flags 644 int layer = ch - ch_; 642 int layer = ch - ch_; //LLL 645 643 Source::Layer& sl = s.layer(layer); 646 644 timeval now = unixtime(); 647 645 sl.lts_ctrl(now); 648 646 649 int we_sent = 0;650 rtcp_rr* rr;651 rtcp_xr_hdr* xrh; // extended report header652 rtcp_xr_blk* xrb; // extended report block653 Tcl& tcl = Tcl::instance();654 655 MediaTimer* mt = MediaTimer::instance();656 if (sl.np() != last_np_ && mt) {657 last_np_ = sl.np();658 we_sent = 1;659 flags |= RTCP_PT_SR;660 rtcp_sr* sr = (rtcp_sr*)(rh + 1);661 sr->sr_ntp = ntp64time(now);662 HTONL(sr->sr_ntp.upper);663 HTONL(sr->sr_ntp.lower);664 sr->sr_ts = htonl(mt->ref_ts());665 sr->sr_np = htonl(sl.np());666 sr->sr_nb = htonl(sl.nb());667 rr = (rtcp_rr*)(sr + 1);668 } else {669 flags |= RTCP_PT_RR;670 rr = (rtcp_rr*)(rh + 1);671 }672 673 647 // set RTCP flag to XR packet 674 flags |= RTCP_PT_XR; 675 // access XR header 676 xrh = (rtcp_xr_hdr*)(rh + 1); 677 xrb = (rtcp_xr_blk*)(xrh + 1); 678 679 int xrlen = 0x03; // XR packet length 680 int xrssrc = 0; // SSRC of source (currently unused) 648 flags |= RTCP_PT_XR; 649 650 // declare XR packet 651 rtcp_xr* xr; 652 xr = (rtcp_xr*)(rh + 1); 653 654 // ssrc of XR source (currently unused) 655 int xrssrc = 0; 656 xr->ssrc = htonl(xrssrc); // UNUSED 681 657 682 658 // this block is used for giving seqno and ackofack 683 659 if(bt == XR_BT_1) { 684 660 // set XR block flags (block type and length) 685 xrh->xr_flags = htons(XR_BT_1 << 8); 686 xrh->xr_len = htons(xrlen); 687 688 xrb->ssrc = htonl(xrssrc); // UNUSED 689 xrb->end_seq = htons(tfwc_sndr_get_seqno()); 690 xrb->begin_seq = htons(tfwc_sndr_get_aoa()); 691 xrb->chunk = NULL; 661 xr->xr_flags = htons(XR_BT_1 << 8); 662 663 // get current RTP data packet seqno from TfwcSndr 664 xr->end_seq = htons(tfwc_sndr_get_seqno()); 665 666 // get ackofack from TfwcSndr 667 xr->begin_seq = htons(tfwc_sndr_get_aoa()); 668 692 669 debug_msg(" SeqNo: %d\n", tfwc_sndr_get_seqno()); 693 670 } 694 695 671 // this block is used for giving timestamp 696 672 else if(bt == XR_BT_3) { 697 673 // set XR block flags (block type and length) 698 xrh->xr_flags = htons(XR_BT_3 << 8); 699 xrh->xr_len = htons(xrlen); 700 701 xrb->ssrc = htonl(xrssrc); // UNUSED 702 //xrb->end_seq = NULL; // UNUSED 703 //xrb->begin_seq = NULL; // UNUSED 704 xrb->chunk = (u_int32_t *) htonl(tfwc_sndr_get_ts()); 674 xr->xr_flags = htons(XR_BT_3 << 8); 675 676 // get timestamp from TfwcSndr 677 xr->chunk = (u_int32_t *) htonl(tfwc_sndr_get_ts()); 678 705 679 debug_msg(" TS: %d\n", tfwc_sndr_get_ts()); 706 680 } 707 681 708 int nrr = 0; 709 int nsrc = 0; 710 711 u_int inactive = u_int(ch->rint() * (32./1000.)); 712 if (inactive < 2) 713 inactive = 2; 714 for (Source* sp = sm.sources(); sp != 0; sp = sp->next_) { 715 ++nsrc; 716 Source::Layer& sl = sp->layer(layer); 717 int received = sl.np() - sl.snp(); 718 if (received == 0) { 719 if (u_int(now.tv_sec - sl.lts_ctrl().tv_sec) > inactive) 720 --nsrc; 721 continue; 722 } 723 sl.snp(sl.np()); 724 rr->rr_srcid = sp->srcid(); 725 int expected = sl.ns() - sl.sns(); 726 sl.sns(sl.ns()); 727 u_int32_t v; 728 int lost = expected - received; 729 730 if (lost <= 0) 731 v = 0; 732 else 733 /* expected != 0 if lost > 0 */ 734 v = ((lost << 8) / expected) << 24; 735 736 /* XXX should saturate on over/underflow */ 737 v |= (sl.ns() - sl.np()) & 0xffffff; 738 rr->rr_loss = htonl(v); 739 rr->rr_ehsr = htonl(sl.ehs()); 740 rr->rr_dv = (sp->handler() != 0) ? sp->handler()->delvar() : 0; 741 rr->rr_lsr = htonl(sl.sts_ctrl()); 742 743 if (sl.lts_ctrl().tv_sec == 0) 744 rr->rr_dlsr = 0; 745 else { 746 u_int32_t ntp_now = ntptime(now); 747 u_int32_t ntp_then = ntptime(sl.lts_ctrl()); 748 rr->rr_dlsr = htonl(ntp_now - ntp_then); 749 } 750 ++rr; 751 if (++nrr >= 31) 752 break; 753 } 754 755 flags |= nrr << 8; 682 // XR report block length 683 int xrlen = (u_char*)xr - pktbuf_; 684 xr->xr_len = htons((xrlen >> 2) - 1); 685 686 // RTCP header flags (this is not the XR header flags) 756 687 rh->rh_flags = htons(flags); 757 int len = (u_char*)rr - pktbuf_; 688 689 // RTCP packet length 690 int len = (u_char *) xr - pktbuf_; 758 691 rh->rh_len = htons((len >> 2) - 1); 759 692 760 if (bye) 761 len += build_bye((rtcphdr*)rr, s); 762 else 763 len += build_sdes((rtcphdr*)rr, s); 764 765 // build "site" app data if specified 766 const char *data = tcl.attr("site"); 767 if(data) 768 { 769 rr = (rtcp_rr*)(((u_char*)rh) + len); 770 len += build_app((rtcphdr*)rr, s, "site", (void *)data, strlen(data)); 771 } 772 773 // sending XR report packet 693 // send XR report block 774 694 ch->send(pktbuf_, len); 775 695 } … … 1229 1149 s->layer(layer).lts_ctrl(unixtime()); 1230 1150 int cnt = flags >> 8 & 0x1f; // reception report count 1231 parse_xr_records(ssrc, (rtcp_xr _hdr*)(rh + 1), cnt, ep, addr);1232 } 1233 1234 void SessionManager::parse_xr_records(u_int32_t ssrc, rtcp_xr _hdr* xrh, int cnt,1151 parse_xr_records(ssrc, (rtcp_xr*)(rh + 1), cnt, ep, addr); 1152 } 1153 1154 void SessionManager::parse_xr_records(u_int32_t ssrc, rtcp_xr* xr, int cnt, 1235 1155 const u_char* ep, Address & addr) 1236 1156 { … … 1239 1159 UNUSED(addr); 1240 1160 1241 int xrlen = ntohs(xrh->xr_len); 1242 rtcp_xr_blk* xrb = (rtcp_xr_blk*)(xrh + 1); 1161 int xrlen = ntohs(xr->xr_len) << 2; 1162 u_int16_t ackofack = ntohs(xr->begin_seq); 1163 u_int16_t seqno = ntohs(xr->end_seq); 1164 debug_msg("AoA: %d, SEQNO: %d\n", ackofack, seqno); 1243 1165 1244 1166 // we received seqno/ackofack, so do receiver stuffs here 1245 if ( xrb->chunk == NULL) {1167 if (seqno != ackofack) { 1246 1168 printf("RECEIVER RECEIVER!!\n"); 1247 1169 // parse seqno, ackofack, and timestamp from XR report block 1248 if(xr h->xr_flags >> 8 == XR_BT_1) {1249 ackofack_ = ntohs(xrb->begin_seq);1250 seqno_ = ntohs(xrb->end_seq);1251 } 1252 else if(xr h->xr_flags >> 8 == XR_BT_3) {1253 ts_ = ntohl((u_int32_t) &xr b->chunk);1170 if(xr->xr_flags >> 8 == XR_BT_1) { 1171 ackofack_ = ackofack; 1172 seqno_ = seqno; 1173 } 1174 else if(xr->xr_flags >> 8 == XR_BT_3) { 1175 ts_ = ntohl((u_int32_t) &xr->chunk); 1254 1176 } 1255 1177 … … 1258 1180 1259 1181 // send receiver side XR report 1260 ch_[0].send(build_ackv_pkt(xr h, ssrc), xrlen);1261 ch_[0].send(build_ts_echo_pkt(xr h, ssrc), xrlen);1182 ch_[0].send(build_ackv_pkt(xr, ssrc), xrlen); 1183 ch_[0].send(build_ts_echo_pkt(xr, ssrc), xrlen); 1262 1184 } 1263 1185 // we received ackvec, so do sender stuffs here … … 1265 1187 printf("SENDER SENDER!!\n"); 1266 1188 // parse seqno, ackvec and timestamp echo from XR report block 1267 if(xr h->xr_flags >> 8 == XR_BT_1) {1268 ackvec_ = ntohl((u_int32_t) &xr b->chunk);1269 } 1270 else if(xr h->xr_flags >> 8 == XR_BT_3) {1271 ts_echo_ = ntohl((u_int32_t) &xr b->chunk);1189 if(xr->xr_flags >> 8 == XR_BT_1) { 1190 ackvec_ = ntohl((u_int32_t) &xr->chunk); 1191 } 1192 else if(xr->xr_flags >> 8 == XR_BT_3) { 1193 ts_echo_ = ntohl((u_int32_t) &xr->chunk); 1272 1194 } 1273 1195 … … 1278 1200 1279 1201 // build ackvec packet (RTCP XR packet) 1280 u_char* SessionManager::build_ackv_pkt(rtcp_xr_hdr* xrh, u_int32_t ssrc) 1281 { 1202 u_char* SessionManager::build_ackv_pkt(rtcp_xr* xr, u_int32_t ssrc) 1203 { 1204 xr->ssrc = htons(ssrc); // UNUSED 1205 1282 1206 // set XR block type 1283 xr h->xr_flags = XR_BT_1 << 8;1284 1285 // take XR block contents1286 rtcp_xr_blk* xrb = (rtcp_xr_blk*)(xrh + 1);1287 1288 xrb->ssrc = htons(ssrc); // UNUSED1289 xr b->chunk = (u_int32_t *) htonl(tfwc_rcvr_getvec());1290 1291 u_char* p = (u_char*) xr h;1207 xr->xr_flags = XR_BT_1 << 8; 1208 1209 // make 'begin_seq' equal to 'end_seq' 1210 xr->begin_seq = xr->end_seq; 1211 1212 // get ackvec from TfwcRcvr 1213 xr->chunk = (u_int32_t *) htonl(tfwc_rcvr_getvec()); 1214 1215 u_char* p = (u_char*) xr; 1292 1216 return (p); 1293 1217 } 1294 1218 1295 1219 // build timestamp packet (RTCP XR packet) 1296 u_char* SessionManager::build_ts_echo_pkt(rtcp_xr_hdr* xrh, u_int32_t ssrc) 1297 { 1220 u_char* SessionManager::build_ts_echo_pkt(rtcp_xr* xr, u_int32_t ssrc) 1221 { 1222 xr->ssrc = htons(ssrc); // UNUSED 1223 1298 1224 // set XR block type 1299 xrh->xr_flags = XR_BT_3 << 8; 1300 1301 // take XR block contents 1302 rtcp_xr_blk* xrb = (rtcp_xr_blk*)(xrh + 1); 1303 1304 xrb->ssrc = htons(ssrc); // UNUSED 1305 xrb->chunk = (u_int32_t *) htonl(tfwc_rcvr_ts_echo()); 1306 1307 u_char* p = (u_char*) xrh; 1225 xr->xr_flags = XR_BT_3 << 8; 1226 1227 // get timestamp echo from TfwcRcvr 1228 xr->chunk = (u_int32_t *) htonl(tfwc_rcvr_ts_echo()); 1229 1230 u_char* p = (u_char*) xr; 1308 1231 return (p); 1309 1232 } -
vic/branches/cc/rtp/session.h
r4259 r4260 131 131 // virtual void send_report(); 132 132 virtual void send_report(CtrlHandler*, int bye, int app = 0); 133 virtual void send_xreport(CtrlHandler*, int b ye, int app = 0);133 virtual void send_xreport(CtrlHandler*, int bt, int bye); 134 134 void build_aoa_pkt(CtrlHandler* ch); 135 135 void build_ts_pkt(CtrlHandler* ch); … … 155 155 void parse_rr_records(u_int32_t ssrc, rtcp_rr* r, int cnt, 156 156 const u_char* ep, Address & addr); 157 void parse_xr_records(u_int32_t ssrc, rtcp_xr _hdr* xrh, int cnt,157 void parse_xr_records(u_int32_t ssrc, rtcp_xr* xr, int cnt, 158 158 const u_char* ep, Address & addr); 159 159 int sdesbody(u_int32_t* p, u_char* ep, Source* ps, … … 162 162 Address & addr, u_int32_t ssrc, int layer); 163 163 void parse_bye(rtcphdr* rh, int flags, u_char* ep, Source* ps); 164 u_char* build_ackv_pkt(rtcp_xr _hdr* xrh, u_int32_t ssrc);165 u_char* build_ts_echo_pkt(rtcp_xr _hdr* xrh, u_int32_t ssrc);164 u_char* build_ackv_pkt(rtcp_xr* xr, u_int32_t ssrc); 165 u_char* build_ts_echo_pkt(rtcp_xr* xr, u_int32_t ssrc); 166 166 167 167 int parseopts(const u_char* bp, int cc, Address & addr) const;
