[Sumover-dev] [svn commit] r4252 - in vic/branches/cc: rtp
sumover-dev at cs.ucl.ac.uk
sumover-dev at cs.ucl.ac.uk
Fri Aug 8 02:13:23 BST 2008
Author: soohyunc
Date: Fri Aug 8 02:13:20 2008
New Revision: 4252
Modified:
vic/branches/cc/cc/tfwc_rcvr.h
vic/branches/cc/cc/tfwc_sndr.cpp
vic/branches/cc/rtp/rtp.h
vic/branches/cc/rtp/session.cpp
vic/branches/cc/rtp/session.h
Log:
two types of XR packets (one for ackvec and the other for ts)
o now, a separate send_xreport() created
o this way, we could have SR/RR and XR at the same time
o now, two separate methods for ackvec pkt and ts pkt
Todo: currently, send_xreport() is driven by timer. we need to call
send_xreport() upon every ackofack reception.
Modified: vic/branches/cc/cc/tfwc_rcvr.h
==============================================================================
--- vic/branches/cc/cc/tfwc_rcvr.h (original)
+++ vic/branches/cc/cc/tfwc_rcvr.h Fri Aug 8 02:13:20 2008
@@ -51,6 +51,7 @@
protected:
inline u_int32_t get_ackvec() { return tfwcAV; }
+ inline u_int32_t get_timestamp() { return tfwcAV; }
u_int32_t tfwcAV; // AckVec (bit vector)
u_int16_t seqno_; // received RTP packet seqno
u_int16_t lastseq_; // last RTP packet seqno
Modified: vic/branches/cc/cc/tfwc_sndr.cpp
==============================================================================
--- vic/branches/cc/cc/tfwc_sndr.cpp (original)
+++ vic/branches/cc/cc/tfwc_sndr.cpp Fri Aug 8 02:13:20 2008
@@ -50,7 +50,6 @@
seqno_(0)
{
u_int32_t marginvec_ = 0xe0000000;
- debug_msg("XXX %d\n", marginvec_);
}
void TfwcSndr::tfwc_sndr_parse_buf(pktbuf* pb) {
@@ -66,8 +65,6 @@
void TfwcSndr::tfwc_sndr_recv(u_int32_t ackv)
{
- UNUSED(ackv);
-
// the most recent 3 packets will be marked as 1 using marginvec_
ackv_ = ackv | marginvec_;
}
Modified: vic/branches/cc/rtp/rtp.h
==============================================================================
--- vic/branches/cc/rtp/rtp.h (original)
+++ vic/branches/cc/rtp/rtp.h Fri Aug 8 02:13:20 2008
@@ -132,6 +132,10 @@
* RTCP Extended Report.
* (RFC 3611)
*/
+#define XR_BT_1 1 // Loss RLE Report Block
+#define XR_BT_2 2 // Duplicate RLE Report Block
+#define XR_BT_3 3 // Packet Receipt Times Report Block
+#define XR_BT_4 4 // Receiver Reference Time Report Block
struct rtcp_xr_hdr {
u_int32_t xr_flags; /* BT:8 TS:8 LEN:16 */
};
Modified: vic/branches/cc/rtp/session.cpp
==============================================================================
--- vic/branches/cc/rtp/session.cpp (original)
+++ vic/branches/cc/rtp/session.cpp Fri Aug 8 02:13:20 2008
@@ -592,6 +592,133 @@
void SessionManager::announce(CtrlHandler* ch)
{
send_report(ch, 0);
+ send_xreport(ch, 0);
+}
+
+/*
+ * Send an RTP extended report packet.
+ */
+void SessionManager::send_xreport(CtrlHandler* ch, int bye, int app)
+{
+ UNUSED(app);
+ UNUSED(bye);
+
+ SourceManager& sm = SourceManager::instance();
+ Source& s = *sm.localsrc();
+ rtcphdr* rh = (rtcphdr*)pktbuf_;
+ rh->rh_ssrc = s.srcid();
+ int flags = RTP_VERSION << 14;
+ int layer = ch - ch_;
+ Source::Layer& sl = s.layer(layer);
+ timeval now = unixtime();
+ sl.lts_ctrl(now);
+
+ int we_sent = 0;
+ rtcp_rr* rr;
+ rtcp_xr_hdr* xrh; // extended report header
+ rtcp_xr_blk* xrb; // extended report block
+ Tcl& tcl = Tcl::instance();
+
+ MediaTimer* mt = MediaTimer::instance();
+ if (sl.np() != last_np_ && mt) {
+ last_np_ = sl.np();
+ we_sent = 1;
+ flags |= RTCP_PT_SR;
+ rtcp_sr* sr = (rtcp_sr*)(rh + 1);
+ sr->sr_ntp = ntp64time(now);
+ HTONL(sr->sr_ntp.upper);
+ HTONL(sr->sr_ntp.lower);
+ sr->sr_ts = htonl(mt->ref_ts());
+ sr->sr_np = htonl(sl.np());
+ sr->sr_nb = htonl(sl.nb());
+ rr = (rtcp_rr*)(sr + 1);
+ } else {
+ flags |= RTCP_PT_RR;
+ rr = (rtcp_rr*)(rh + 1);
+ }
+
+ // set this to XR packet
+ flags |= RTCP_PT_XR;
+ // access XR header
+ xrh = (rtcp_xr_hdr*)(rh + 1);
+ // XR block length
+ int xrlen = (xrh->xr_flags << 16) >> 16;
+ // access XR block contents
+ xrb = (rtcp_xr_blk*)(xrh + xrlen + 1);
+ // for ackofack
+ xrb->begin_seq = htonl(lastseq_);
+ xrb->end_seq = htonl(seqno_ + 1);
+ // this chunk is ackvec
+ xrb->chunk = (u_int32_t *) htonl(get_ackvec());
+ // this chunk is timestamp echo
+ //xrb->chunk = htonl(mt->ref_ts());
+
+ int nrr = 0;
+ int nsrc = 0;
+
+ u_int inactive = u_int(ch->rint() * (32./1000.));
+ if (inactive < 2)
+ inactive = 2;
+ for (Source* sp = sm.sources(); sp != 0; sp = sp->next_) {
+ ++nsrc;
+ Source::Layer& sl = sp->layer(layer);
+ int received = sl.np() - sl.snp();
+ if (received == 0) {
+ if (u_int(now.tv_sec - sl.lts_ctrl().tv_sec) > inactive)
+ --nsrc;
+ continue;
+ }
+ sl.snp(sl.np());
+ rr->rr_srcid = sp->srcid();
+ int expected = sl.ns() - sl.sns();
+ sl.sns(sl.ns());
+ u_int32_t v;
+ int lost = expected - received;
+
+ if (lost <= 0)
+ v = 0;
+ else
+ /* expected != 0 if lost > 0 */
+ v = ((lost << 8) / expected) << 24;
+
+ /* XXX should saturate on over/underflow */
+ v |= (sl.ns() - sl.np()) & 0xffffff;
+ rr->rr_loss = htonl(v);
+ rr->rr_ehsr = htonl(sl.ehs());
+ rr->rr_dv = (sp->handler() != 0) ? sp->handler()->delvar() : 0;
+ rr->rr_lsr = htonl(sl.sts_ctrl());
+
+ if (sl.lts_ctrl().tv_sec == 0)
+ rr->rr_dlsr = 0;
+ else {
+ u_int32_t ntp_now = ntptime(now);
+ u_int32_t ntp_then = ntptime(sl.lts_ctrl());
+ rr->rr_dlsr = htonl(ntp_now - ntp_then);
+ }
+ ++rr;
+ if (++nrr >= 31)
+ break;
+ }
+
+ flags |= nrr << 8;
+ rh->rh_flags = htons(flags);
+ int len = (u_char*)rr - pktbuf_;
+ rh->rh_len = htons((len >> 2) - 1);
+
+ if (bye)
+ len += build_bye((rtcphdr*)rr, s);
+ else
+ len += build_sdes((rtcphdr*)rr, s);
+
+ // build "site" app data if specified
+ const char *data = tcl.attr("site");
+ if(data)
+ {
+ rr = (rtcp_rr*)(((u_char*)rh) + len);
+ len += build_app((rtcphdr*)rr, s, "site", (void *)data, strlen(data));
+ }
+
+ ch->send(pktbuf_, len);
}
/*XXX check for buffer overflow*/
@@ -613,8 +740,8 @@
sl.lts_ctrl(now);
int we_sent = 0;
rtcp_rr* rr;
- rtcp_xr_hdr* xrh; // extended report header
- rtcp_xr_blk* xrb; // extended report block
+ //rtcp_xr_hdr* xrh; // extended report header
+ //rtcp_xr_blk* xrb; // extended report block
Tcl& tcl = Tcl::instance();
/*
@@ -640,7 +767,7 @@
flags |= RTCP_PT_RR;
rr = (rtcp_rr*)(rh + 1);
}
-
+/*
// if CC is turned on, we need XR report
if (is_cc_on()) {
flags |= RTCP_PT_XR; // setting flags to XR
@@ -652,7 +779,7 @@
xrb->chunk = (u_int32_t *) htonl(get_ackvec());
//xrb->chunk = htonl(mt->ref_ts());
}
-
+*/
int nrr = 0;
int nsrc = 0;
/*
@@ -1008,6 +1135,7 @@
void SessionManager::parse_sr(rtcphdr* rh, int flags, u_char*ep,
Source* ps, Address & addr, int layer)
{
+ debug_msg("XXX parse_sr() called!\n");
rtcp_sr* sr = (rtcp_sr*)(rh + 1);
Source* s;
u_int32_t ssrc = rh->rh_ssrc;
@@ -1076,7 +1204,7 @@
void SessionManager::parse_xr_records(u_int32_t ssrc, rtcp_xr_hdr* xrh, int cnt,
const u_char* ep, Address & addr)
{
- debug_msg("XXX parse_xr_records\n");
+ debug_msg("XXX parse_xr_records() called!");
UNUSED(cnt);
UNUSED(ep);
UNUSED(addr);
@@ -1090,7 +1218,8 @@
if (xrb->begin_seq == xrb->end_seq) {
// we received ackofack, so do receiver stuffs here
//trim_vec(xrb->chunk); // chunk in xrb is ackvec
- ch_[0].send(build_ackvpkt(xrh), xrlen);
+ ch_[0].send(build_ackvpkt(xrh, ssrc), xrlen);
+ ch_[0].send(build_tspkt(xrh, ssrc), xrlen);
} else {
// we received ackvec, so do sender stuffs here
ackvec_ = (u_int32_t) &xrb->chunk;
@@ -1100,8 +1229,36 @@
}
}
-u_char* SessionManager::build_ackvpkt(rtcp_xr_hdr* xrh)
+// build ackvec packet (RTCP XR packet)
+u_char* SessionManager::build_ackvpkt(rtcp_xr_hdr* xrh, u_int32_t ssrc)
{
+ // set XR block type
+ xrh->xr_flags |= 0x01000000;
+
+ // take XR block contents
+ int xrlen = (xrh->xr_flags << 16) >> 16;
+ rtcp_xr_blk* xrb = (rtcp_xr_blk*)(xrh + xrlen + 1);
+
+ xrb->ssrc = ssrc;
+ xrb->chunk = (u_int32_t *) get_ackvec();
+
+ u_char* p = (u_char*) xrh;
+ return (p);
+}
+
+// build timestamp packet (RTCP XR packet)
+u_char* SessionManager::build_tspkt(rtcp_xr_hdr* xrh, u_int32_t ssrc)
+{
+ // set XR block type
+ xrh->xr_flags |= 0x03000000;
+
+ // take XR block contents
+ int xrlen = (xrh->xr_flags << 16) >> 16;
+ rtcp_xr_blk* xrb = (rtcp_xr_blk*)(xrh + xrlen + 1);
+
+ xrb->ssrc = ssrc;
+ //xrb->chunk = (u_int32_t *) echo_timestamp();
+
u_char* p = (u_char*) xrh;
return (p);
}
Modified: vic/branches/cc/rtp/session.h
==============================================================================
--- vic/branches/cc/rtp/session.h (original)
+++ vic/branches/cc/rtp/session.h Fri Aug 8 02:13:20 2008
@@ -127,6 +127,7 @@
virtual inline void send_bye() { send_report(&ch_[0], 1); }
// virtual void send_report();
virtual void send_report(CtrlHandler*, int bye, int app = 0);
+ virtual void send_xreport(CtrlHandler*, int bye, int app = 0);
protected:
// void demux(rtphdr* rh, u_char* bp, int cc, Address & addr, int layer);
@@ -155,7 +156,8 @@
void parse_sdes(rtcphdr* rh, int flags, u_char* ep, Source* ps,
Address & addr, u_int32_t ssrc, int layer);
void parse_bye(rtcphdr* rh, int flags, u_char* ep, Source* ps);
- u_char* build_ackvpkt(rtcp_xr_hdr* xrh);
+ u_char* build_ackvpkt(rtcp_xr_hdr* xrh, u_int32_t ssrc);
+ u_char* build_tspkt(rtcp_xr_hdr* xrh, u_int32_t ssrc);
int parseopts(const u_char* bp, int cc, Address & addr) const;
int ckid(const char*, int len);
More information about the Sumover-dev
mailing list