[Sumover-dev] [svn commit] r4730 - in vic/branches/cc: rtp

sumover-dev at cs.ucl.ac.uk sumover-dev at cs.ucl.ac.uk
Sat Mar 27 06:02:11 GMT 2010


Author: soohyunc
Date: Sat Mar 27 06:02:11 2010
New Revision: 4730

Modified:
   vic/branches/cc/cc/tfwc_sndr.cpp
   vic/branches/cc/cc/tfwc_sndr.h
   vic/branches/cc/rtp/session.cpp
   vic/branches/cc/rtp/session.h
   vic/branches/cc/rtp/transmitter.cpp
   vic/branches/cc/rtp/transmitter.h

Log:
o  clear up packet/ackvec re-ordering rules

(1) on packet re-ordering, trigger packet only if the disorder is beyond 3
DUPACK rule. otherwise, just insert the just received seqno to the previously
received ackvec, and re-construct seqno vector from it.

(2) on ack re-ordering, trigger packet only if the disorder is beyond 3 DUPACK
rule. otherwise, don't do anything, because this seqno is already represented
in the previously received ackvec.

(3) if this ack's highest seqno is older than AoA, then simply trigger packt
out, and do nothing else.


o  moved debugging printf statements to the header files.




Modified: vic/branches/cc/cc/tfwc_sndr.cpp
==============================================================================
--- vic/branches/cc/cc/tfwc_sndr.cpp	(original)
+++ vic/branches/cc/cc/tfwc_sndr.cpp	Sat Mar 27 06:02:11 2010
@@ -131,6 +131,9 @@
 	pvec_ = (u_int16_t *)malloc(sizeof(u_int16_t) * num_vec_);
 	clear_pvec(num_vec_);
 	__jacked_ = 0;
+
+	// packet reordering
+	reorder_ = false;
 }
 
 void TfwcSndr::tfwc_sndr_send(int seqno, double now) {
@@ -160,7 +163,7 @@
  * main TFWC reception path
  */
 void TfwcSndr::tfwc_sndr_recv(u_int16_t type, u_int16_t begin, u_int16_t end,
-		u_int16_t *chunk, double so_rtime)
+		u_int16_t *chunk, double so_rtime, bool recv_by_ch, pktbuf* pb)
 {
   switch (type) {
   // retrieve ackvec
@@ -171,9 +174,10 @@
 	// so_timestamp (timestamp for packet reception)
 	so_recv_ = so_rtime;
 	// packet reordering?
-	bool reorder = false;
+	reorder_ = false;
 	// reordered ack delivery?
-	bool outofack = false;
+	bool outofack = false; 
+	UNUSED(outofack);
 
 	// get start/end seqno that this XR chunk reports
 	begins_ = begin;	// lowest packet seqno
@@ -183,9 +187,7 @@
 	// i.e.,) head seqno(= highest seqno) of this ackvec
 	jacked_ = ends_ - 1;
 
-	//fprintf(stderr, 
-	//"    [%s +%d] begins: %d ends: %d jacked: %d\n", 
-	//	__FILE__, __LINE__, begins_, ends_, jacked_);
+	//print_xr_info();
 
 	// get the number of AckVec chunks
 	//   use seqno space to work out the num chunks
@@ -202,25 +204,33 @@
 	clone_ackv(chunk, num_vec_);
 	//print_vec(ackv_, num_vec_);
 
+	//---------------------------------------------------------*
 	// detect packet reordering and reordered ack delivery
 	int shift = abs(__jacked_ - jacked_);
 	if (jacked_ < __jacked_) {
+		//
 		// this ack is deprecated message (e.g., too old).
+		//
 		if(jacked_ < aoa_) {
 		  debug_msg("warning: this ack(%d) is older than AoA(%d)!\n", jacked_,aoa_);
 		  // trigger packets out to keep Jacob's packet conservation rule
-		  cc_tfwc_output();
+		  packet_clocking(pb, recv_by_ch);
 		  return;
 		}
+		//
 		// this ack is delivered out-of-order
+		//
 		else if(out_of_ack(jacked_, seqvec_, num_seqvec_)) {
 		  debug_msg("warning: this ack(%d) itself is out-of-order!\n",jacked_);
-		  outofack = true;
+		  // if the disorder is beyond 3 dupack rule,
 		  // trigger packets out to keep Jacob's packet conservation rule
-		  cc_tfwc_output();
+		  if(shift >= DUPACKS)
+		  packet_clocking(pb, recv_by_ch);
 		  return;
 		}
+		//
 		// packet is out-of-order, so adjust ackvec re-construction
+		//
 		else {
 		  debug_msg("warning: packet reordering occurred!\n");
 		  // replace just ack'ed seqno
@@ -228,16 +238,17 @@
 		  // re-calculate numelm and numvec
 		  num_elm_ = get_numelm(begins_, jacked_);
 		  num_vec_ = get_numvec(num_elm_);
-		  reorder = true;
+		  reorder_ = true;
 		}
 	}
 	else {
 		free(pvec_);
 	}
+	//---------------------------------------------------------*
 
 	// if packet reordering occurred, insert re-ordered seqno
 	// into the received ackvec using previously received ackvec
-	if(reorder) {
+	if(reorder_) {
 		for (int i = 0; i < num_vec_; i++) {
 		ackv_[i] = (ackv_[i] << shift) | pvec_[i];
 		}
@@ -265,32 +276,38 @@
 	// 	@end: mvec_[DUPACKS-1] - 1
 	gen_refvec(mvec_[DUPACKS-1]-1, aoa_+1);
 
+	// we have detected packet re-ordering!!!
+	// so, we've updated/corrected received ackvec
+	// by inserting "jacked" to the previous ackvec.
+	// finally, we only need to clock packets out.
+	// (i.e., do NOT update cwnd and RTT)
+	if(reorder_) {
+		// triggering only if the disorder is beyond 3 dupack rule,
+		if (shift >= DUPACKS)
+		packet_clocking(pb, recv_by_ch);
+		reset_var();
+		return;
+	}
+
 	// TFWC is not turned on (i.e., no packet loss yet)
 	if(!is_tfwc_on_) {
-		if(detect_loss()) {
-			is_tfwc_on_ = true;
-			dupack_action();
-			ts_ = tsvec_[first_lost_pkt_%TSZ];
-		} else {
-			// TCP-like AIMD control
-			cwnd_ += 1;
-		}
+		if(detect_loss())
+		dupack_action(); 
+		else
+		cwnd_++; // TCP-like AIMD
 	} 
 	// TFWC is turned on, so control that way
 	else {
 		control();
 	}
-	fprintf(stderr, "\tnow: %f\tcwnd: %d\n", so_recv_, cwnd_);
 
 	// set ackofack (real number)
 	aoa_ = ackofack(); 
 
-	if(!reorder) {
 	// sampled RTT
 	tao_ = so_recv_ - tsvec_[jacked_%TSZ];
 	// update RTT with the sampled RTT
 	update_rtt(tao_);
-	}
 
 	// is TFWC being driven by timeout mechanism?
 	if(to_driven_ && is_tfwc_on_)
@@ -435,7 +452,7 @@
 		// record the very first lost packet seqno
 		if(!is_there) {
 			if(!is_first_loss_seen_) 
-				first_lost_pkt_ = refvec_[i];
+			first_lost_pkt_ = refvec_[i];
 		}
 	}
 	return ret = (count > 0) ? true : false;
@@ -499,8 +516,7 @@
 	if (rto_ > maxrto_)
 		rto_ = maxrto_;
 
-	fprintf(stderr, "\t<< now_: %f tsvec_[%d]: %f rtt: %f srtt: %f\n", 
-		so_recv_, jacked_%TSZ, tsvec_[jacked_%TSZ], tao_, srtt_);
+	print_rtt_info();
 }
 
 /*
@@ -533,6 +549,8 @@
 	// cwnd should always be greater than 1
 	if (cwnd_ < 1)
 		cwnd_ = 1;
+	
+	print_cwnd();
 }
 
 /*
@@ -603,6 +621,11 @@
 
 	// generate weight factors
 	gen_weight();
+
+	// finally, record the very first lost packet's timestamp
+	ts_ = tsvec_[first_lost_pkt_%TSZ];
+	// then, turn on TFWC algo
+	is_tfwc_on_ = true;
 }
 
 /*
@@ -715,7 +738,7 @@
 
 	// this is average loss interval
 	avg_interval_ = I_tot_ / tot_weight_;
-	fprintf(stderr, "\tnow: %f\tALI: %f\n\n", now(), avg_interval_);
+	print_ALI();
 }
 
 /*
@@ -794,3 +817,13 @@
 
 	rto_ = (term1 + term2) * sqrt(rtt)/sqrtrtt_;
 }
+
+/*
+ * clokcing packet out on re-ordering detection
+ */
+void TfwcSndr::packet_clocking (pktbuf* pb, bool flag) {
+	if (flag)
+		cc_tfwc_trigger();
+	else
+		cc_tfwc_trigger(pb);
+}

Modified: vic/branches/cc/cc/tfwc_sndr.h
==============================================================================
--- vic/branches/cc/cc/tfwc_sndr.h	(original)
+++ vic/branches/cc/cc/tfwc_sndr.h	Sat Mar 27 06:02:11 2010
@@ -78,15 +78,18 @@
 	TfwcSndr();
 	virtual ~TfwcSndr() {};
 
-	virtual void cc_tfwc_output() = 0;
+	virtual void cc_tfwc_output(bool recv_by_ch=0) = 0;
+	virtual void cc_tfwc_output(pktbuf*) = 0;
+	virtual void cc_tfwc_trigger(pktbuf* pb=0) = 0;
 	virtual double tx_ts_offset() = 0;
+	virtual int tx_buf_size() = 0;
 
 	// parse seqno and timestamp
 	void tfwc_sndr_send(int, double);
 
 	// main reception path (XR packet)
 	void tfwc_sndr_recv(u_int16_t type, u_int16_t begin, u_int16_t end,
-			u_int16_t *chunk, double so_rtime);
+	u_int16_t *chunk, double so_rtime, bool recv_by_ch, pktbuf* pb);
 
 	// return ackofack
 	inline u_int16_t tfwc_sndr_get_aoa() { return aoa_; }
@@ -124,6 +127,10 @@
 	// Rtx timer
 	void expire(int option);
 
+	// packet reordering
+	bool reorder_;
+	inline bool reordering() { return (reorder_); }
+
 protected:
 	// generate sequence numbers
 	void gen_seqvec(u_int16_t *v, int n);
@@ -239,6 +246,9 @@
 	// determine out-of-ordered ack delivery
 	bool out_of_ack (u_int16_t, u_int32_t*, int);
 
+	// keep packet conservation rule
+	void packet_clocking (pktbuf* pb, bool flag);
+
 	// AckVec clone from Vic 
 	inline void clone_ackv(u_int16_t *c, int n) {
 		for (int i = 0; i < n; i++)
@@ -301,6 +311,30 @@
 		__jacked_ = highest;
 	}
 
+	// print cwnd for debugging
+	inline void print_cwnd() {
+	fprintf(stderr, "\tnow: %f\tcwnd: %d\n", so_recv_, cwnd_);
+	}
+
+	// print received XR chunk info
+	inline void print_xr_info() {
+	fprintf(stderr, 
+	"    [%s +%d] begins: %d ends: %d jacked: %d\n", 
+	__FILE__, __LINE__, begins_, ends_, jacked_);
+	}
+
+	// print RTT related info for debugging
+	inline void print_rtt_info() {
+	fprintf(stderr, 
+	"\t<< now_: %f tsvec_[%d]: %f rtt: %f srtt: %f\n",
+	so_recv_, jacked_%TSZ, tsvec_[jacked_%TSZ], tao_, srtt_);
+	}
+
+	// print ALI for debugging
+	inline void print_ALI() {
+	fprintf(stderr, "\tnow: %f\tALI: %f\n\n", so_recv_, avg_interval_);
+	}
+
 	int ndtp_;		// number of data packet sent
 	int nakp_;		// number of ackvec packet received
 	int ntep_;		// number of ts echo packet received

Modified: vic/branches/cc/rtp/session.cpp
==============================================================================
--- vic/branches/cc/rtp/session.cpp	(original)
+++ vic/branches/cc/rtp/session.cpp	Sat Mar 27 06:02:11 2010
@@ -450,19 +450,16 @@
 	return (TCL_ERROR);
 }
 
-void SessionManager::transmit(pktbuf* pb)
+void SessionManager::transmit(pktbuf* pb, bool recv_by_ch)
 {
 	//mh_.msg_iov = pb->iov;
 	//	dh_[.net()->send(mh_);
 		//debug_msg("L %d,",pb->layer);
-	
-	// receive XR before sending
-	recv_xreport(ch_);
 
-	// get seqno
-	rtphdr* rh = (rtphdr *) pb->data;
-	fprintf(stderr, "\n\tnow: %f\tseqno: %d\n\n",
-		tx_now()-tx_now_offset_, ntohs(rh->rh_seqno));
+	// receive XR before sending
+	if(!recv_by_ch)
+	recv_xreport(ch_, pb);
+	print_rtp_seqno(pb);
 
 	// Using loop_layer for now to restrict transmission as well
 	if (pb->layer < loop_layer_) {
@@ -483,15 +480,14 @@
 	}
 }
 
-void SessionManager::tx_data_only(pktbuf* pb) 
+void SessionManager::tx_data_only(pktbuf* pb, bool flag) 
 {
 	// receive XR before sending
-	recv_xreport(ch_);
+	if(flag)
+	recv_xreport(ch_, pb);
 
-	// get seqno
-	rtphdr* rh = (rtphdr *) pb->data;
-	fprintf(stderr, "\n\tnow: %f\tseqno: %d\n\n",
-		tx_now()-tx_now_offset_, ntohs(rh->rh_seqno));
+	// print RTP seqno
+	print_rtp_seqno(pb);
 
 	if (pb->layer < loop_layer_) {
 		Network* n = dh_[pb->layer].net();
@@ -1291,7 +1287,7 @@
 }
 
 void SessionManager::parse_xr(rtcphdr* rh, int flags, u_char* ep,
-					  Source* ps, Address & addr, int layer, int op)
+		Source* ps, Address & addr, int layer, bool recv_by_ch, pktbuf* pb)
 {
 	Source* s;
 	u_int32_t ssrc = rh->rh_ssrc;	// RTCP's ssrc
@@ -1302,14 +1298,13 @@
 
 	s->layer(layer).lts_ctrl(unixtime());
 	int cnt = flags >> 8 & 0x1f;	// reception report count
-	parse_xr_records(ssrc, (rtcp_xr*)(rh + 1), cnt, ep, addr, op);
+	parse_xr_records(ssrc, (rtcp_xr*)(rh + 1), cnt, ep, addr, recv_by_ch, pb);
 }
 
 void SessionManager::parse_xr_records(u_int32_t ssrc, rtcp_xr* xr, int cnt,
-		const u_char* ep, Address & addr, int op)
+		const u_char* ep, Address & addr, bool recv_by_ch, pktbuf* pb)
 {
-	fprintf(stderr, 
-	"~~~~~~~~~~~~~~~~~~entering parse_xr_records()~~~~~~~~~~~~~~~~~~\n");
+	parse_xr_banner_top();
 	UNUSED(ssrc);
 	UNUSED(cnt);
 	UNUSED(ep);
@@ -1322,7 +1317,7 @@
 	rtcp_xr_BT_1_hdr *xr1;
 
 	// so_timestamp
-	double so_rtime;
+	double so_rtime = 0.;
 
 	if ( xr->BT == XR_BT_1 && xr->xr_flag == 0 ) {
 		// XR block type 1
@@ -1339,24 +1334,20 @@
 		// i am an RTP data sender, so do the sender stuffs (AoA)
 		if (am_i_sender()) {
 			fprintf(stderr, ">>> parse_xr - i_am_sender\n");
-			//fprintf(stderr, 
-			//	"    [%s +%d] beg:%d, end:%d, xr1len:%d (xrlen:%d)\n", 
-			//	__FILE__,__LINE__,begin, end, ntohs(xr1->xr_len), xrlen);
-			
+			//sender_xr_info(begin, end, xr1, xrlen);
 			switch (cc_type_) {
 			case WBCC:
 				fprintf(stderr, "\tincomingXR\tnow: %f\n", recv_ts_);
 				// SO_TIMESTAMP
 				//so_rtime = ch_[0].net()->recv_so_time();
-				//fprintf(stderr, "*** recv_ts: %f so_rtime: %f diff: %f\n",
-				//		recv_ts_, so_rtime, recv_ts_-so_rtime);
+				//sender_xr_ts_info(so_rtime);
 
 				// TFWC sender (getting AckVec)
-				tfwc_sndr_recv(xr->BT, begin, end, chunk, recv_ts_);
+				tfwc_sndr_recv(xr->BT, begin, end, chunk, recv_ts_, recv_by_ch, pb);
 
 				// we need to call Transmitter::output(pb) to make Ack driven
-				if(op)
-				cc_tfwc_output();
+				if(recv_by_ch)
+				cc_tfwc_output(recv_by_ch);
 				break;
 
 			case RBCC:
@@ -1368,8 +1359,7 @@
 			switch (cc_type_) {
 			case WBCC:
 				fprintf(stderr, ">>> parse_xr - i_am_receiver\n");
-				fprintf(stderr, "    [%s +%d] chunk[0]:%d\n", 
-					__FILE__,__LINE__, ntohs(chunk[0]));
+				receiver_xr_info(chunk);
 
 				// TFWC receiver (getting ackofack)
 				tfwc_rcvr_recv_aoa(xr->BT, chunk);
@@ -1384,14 +1374,14 @@
 		// XXX
 		debug_msg("UNKNOWN RTCP XR Packet: BT:%d\n", xr->BT);
 	}
-	fprintf(stderr,
-	"-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n");
+	parse_xr_banner_bottom();
 }
 
 // receive XR (AckVec)
-void SessionManager::recv_xreport(CtrlHandler *ch) {
+void SessionManager::recv_xreport(CtrlHandler *ch, pktbuf* pb) {
+	fprintf(stderr, "    retrieve XR-----------------\n");
 	// timestamp for XR reception
-	recv_ts_ = tx_now() - tx_now_offset_;
+	recv_ts_ = tx_get_now();
 
 	Address * srcp;
 	int cc = ch->recv(pktbuf_, 2 * RTP_MTU, srcp);
@@ -1464,7 +1454,7 @@
 		switch (flags & 0xff) {
 		case RTCP_PT_XR:
 			rtcp_pkt_id = RTCP_PT_XR;
-			parse_xr(rh, flags, ep, ps, addr, layer, 0);
+			parse_xr(rh, flags, ep, ps, addr, layer, 0, pb);
 			break;
 		case RTCP_PT_SR:
 			rtcp_pkt_id = RTCP_PT_SR;
@@ -1482,6 +1472,7 @@
 		}
 		rh = (rtcphdr *)ep;
 	}
+	fprintf(stderr, "--------------------------------\n");
 	return;
 }
 
@@ -1617,7 +1608,7 @@
 void SessionManager::recv(CtrlHandler* ch)
 {
 	// timestamp for XR reception 
-	recv_ts_ = tx_now() - tx_now_offset_;
+	recv_ts_ = tx_get_now();
 
 	Address * srcp;
 	int cc = ch->recv(pktbuf_, 2 * RTP_MTU, srcp);

Modified: vic/branches/cc/rtp/session.h
==============================================================================
--- vic/branches/cc/rtp/session.h	(original)
+++ vic/branches/cc/rtp/session.h	Sat Mar 27 06:02:11 2010
@@ -147,7 +147,7 @@
 		u_int32_t xrssrc);
 
 	// receive XR
-	void recv_xreport(CtrlHandler*);
+	void recv_xreport(CtrlHandler*, pktbuf*);
 
 	void build_aoa_pkt(CtrlHandler* ch);
 	void build_ts_pkt(CtrlHandler* ch);
@@ -162,8 +162,8 @@
 //	void demux(rtphdr* rh, u_char* bp, int cc, Address & addr, int layer);
 	void demux(pktbuf* pb, Address & addr);
 	virtual int check_format(int fmt) const = 0;
-	virtual void transmit(pktbuf* pb);
-	virtual void tx_data_only(pktbuf* pb);
+	virtual void transmit(pktbuf* pb, bool recv_by_ch=0);
+	virtual void tx_data_only(pktbuf* pb, bool flag);
 	void send_report(int bye);
 	void send_ECNXreport(CtrlHandler* ch, u_int8_t tos, u_int16_t begin_seq);
 	int build_bye(rtcphdr* rh, Source& local);
@@ -177,11 +177,11 @@
 	void parse_rr(rtcphdr* rh, int flags, u_char* ep,
 		      Source* ps, Address & addr, int layer);
 	void parse_xr(rtcphdr* rh, int flags, u_char* ep,
-		      Source* ps, Address & addr, int layer, int op);
+		      Source* ps, Address & addr, int layer, bool recv_by_ch, pktbuf* pb=0);
 	void parse_rr_records(u_int32_t ssrc, rtcp_rr* r, int cnt,
 			      const u_char* ep, Address & addr);
 	void parse_xr_records(u_int32_t ssrc, rtcp_xr* xr, int cnt,
-			      const u_char* ep, Address & addr, int op);
+			      const u_char* ep, Address & addr, bool recv_by_ch, pktbuf* pb);
 	int sdesbody(u_int32_t* p, u_char* ep, Source* ps,
 		     Address & addr, u_int32_t ssrc, int layer);
 	void parse_sdes(rtcphdr* rh, int flags, u_char* ep, Source* ps,
@@ -236,6 +236,45 @@
 	u_int16_t ackvec_;	// this is a bit vector
 	// timestamp
 	double recv_ts_;	// receive timestamp
+
+private:
+	// print RTP data packet's seqno
+	inline void print_rtp_seqno(u_int16_t seqno) {
+	fprintf(stderr, "\n\tnow: %f\tseqno: %d\n\n",tx_get_now(),seqno);
+	}
+	inline void print_rtp_seqno(pktbuf* pb) {
+	rtphdr* rh = (rtphdr *) pb->data;
+	fprintf(stderr, "\n\tnow: %f\tseqno: %d\n\n",
+		tx_get_now(),ntohs(rh->rh_seqno));
+	}
+
+	// print sender's XR info
+	inline void sender_xr_info(u_int16_t b, 
+		u_int16_t e, 
+		rtcp_xr_BT_1_hdr* xrh,
+		u_int16_t l) 
+	{
+		debug_msg("beg:%d, end:%d, xr1len:%d (xrlen:%d)\n",
+		b,e,ntohs(xrh->xr_len),l);
+	}
+	// print sender's XR info
+	inline void sender_xr_ts_info(double ts) {
+	fprintf(stderr, "*** recv_ts: %f so_rtime: %f diff: %f\n",
+		recv_ts_, ts, recv_ts_-ts);
+	}
+	// print receiver's XR info
+	inline void receiver_xr_info(u_int16_t *c) {
+		debug_msg("chunk[0]:%d\n", ntohs(c[0]));
+	}
+	// print parse XR banner
+	inline void parse_xr_banner_top() {
+	fprintf(stderr,
+	"~~~~~~~~~~~~~~~~~~entering parse_xr_records()~~~~~~~~~~~~~~~~~~\n");
+	}
+	inline void parse_xr_banner_bottom() {
+	fprintf(stderr,
+	"-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n");
+	}
 };
 
 class AudioSessionManager : public SessionManager {

Modified: vic/branches/cc/rtp/transmitter.cpp
==============================================================================
--- vic/branches/cc/rtp/transmitter.cpp	(original)
+++ vic/branches/cc/rtp/transmitter.cpp	Sat Mar 27 06:02:11 2010
@@ -65,6 +65,9 @@
 extern "C" writev(int, iovec*, int);
 #endif
 
+#define NO_XR_RECV 0
+#define XR_RECV 1
+
 //Transmitter::pktbuf* Transmitter::freehdrs_;
 //Transmitter::buffer* Transmitter::freebufs_;
 int Transmitter::nbufs_;
@@ -313,10 +316,7 @@
 
 void Transmitter::cc_tfwc_output(pktbuf* pb) 
 {
-//	fprintf(stderr,"\t--------entering cc_tfwc_output(pb)---------\n");
-//	fprintf(stderr,"\t|                                          |\n");
-//	fprintf(stderr,"\tV                                          V\n");
-
+	//cc_output_banner_top();
 	// pb is not null, hence parse it.
 	rtphdr* rh = (rtphdr *) pb->data;
 
@@ -327,26 +327,21 @@
 	
 	if (ntohs(rh->rh_seqno) <= magic + jack) {
 		// record seqno and timestamp at TfwcSndr side
-		tfwc_sndr_send(ntohs(rh->rh_seqno), tx_now()-tx_now_offset_);
+		tfwc_sndr_send(ntohs(rh->rh_seqno), tx_get_now());
 		// move head pointer
 		head_ = pb->next;
-		// call Transmitter::output_data_only(pb)
-		output_data_only(pb);
+		// call Transmitter::output_data_only w/ XR reception
+		output_data_only(pb, XR_RECV);
 	}
-//	fprintf(stderr,"\t^                                          ^\n");
-//	fprintf(stderr,"\t|                                          |\n");
-//	fprintf(stderr,"\t============================================\n");
+	//cc_output_banner_bottom();
 }
 
 /*
  * main TFWC CC output routines
  */
-void Transmitter::cc_tfwc_output()
+void Transmitter::cc_tfwc_output(bool recv_by_ch)
 {
-//	fprintf(stderr,"\t---------entering cc_tfwc_output()----------\n");
-//	fprintf(stderr,"\t|                                          |\n");
-//	fprintf(stderr,"\tV                                          V\n");
-
+	//cc_output_banner_top();
 	// head of the RTP data packet buffer (pb)
 	pktbuf* pb = head_;
 
@@ -359,7 +354,6 @@
 		return;
 	}
 
-	//printf("\tthere are packets available to send in cc_tfwc_output()\n");
 	// pb is not null, hence parse it.
 	rtphdr* rh = (rtphdr *) pb->data;
 
@@ -372,16 +366,16 @@
 //	debug_msg("jack: %d\n", jack);
 
 	//fprintf(stderr, "\tXXX now: %f\tnum: %d\tcwnd: %d\tjack: %d\n",
-	//tx_now()-tx_now_offset_, ntohs(rh->rh_seqno), magic, jack);
+	//tx_get_now(), ntohs(rh->rh_seqno), magic, jack);
 
 	// while packet seqno is within "cwnd + jack", send that packet
 	while (ntohs(rh->rh_seqno) <= magic + jack) {
 		// record seqno and timestamp at TfwcSndr side
-		tfwc_sndr_send(ntohs(rh->rh_seqno), tx_now()-tx_now_offset_);
+		tfwc_sndr_send(ntohs(rh->rh_seqno), tx_get_now());
 		// move head pointer
 		head_ = pb->next;
 		// call Transmitter::output(pb)
-		output(pb);
+		output(pb, recv_by_ch);
 
 		// if the moved head pointer is not null, parse packet buffer.
 		// otherwise, break while statement.
@@ -392,9 +386,33 @@
 			break;
 		}
 	} // end while ()
-//	fprintf(stderr,"\t^                                          ^\n");
-//	fprintf(stderr,"\t|                                          |\n");
-//	fprintf(stderr,"\t============================================\n");
+	//cc_output_banner_bottom();
+}
+
+/*
+ * trigger packet out forcefully
+ */
+void Transmitter::cc_tfwc_trigger(pktbuf* pb) {
+	// if pb is null here, it means this routine was called 
+	// by SessionManager::recv(CtrlHandler* ch).
+	// therefore, assign pktbuf's head to pb.
+	if (pb == 0)
+	pb = head_;
+
+	// if pb is null here, it means the actual pkbuf is empty!
+	if (pb == 0) {
+		is_buf_empty_ = true;
+		return;
+	}
+
+	// parse pb data
+	rtphdr* rh = (rtphdr *) pb->data;
+	// record seqno and timestamp at TfwcSndr side
+	tfwc_sndr_send(ntohs(rh->rh_seqno), tx_get_now());
+	// move head pointer
+	head_ = pb->next;
+	// call Transmitter::output_data_only w/o XR reception
+	output_data_only(pb, NO_XR_RECV);
 }
 
 /*
@@ -444,20 +462,20 @@
 	}
 }
 
-void Transmitter::output(pktbuf* pb)
+void Transmitter::output(pktbuf* pb, bool recv_by_ch)
 {
 	//fprintf(stderr, "\n\tTransmitter::output()\n");
 	//if (dumpfd_ >= 0)
 	//	dump(dumpfd_, pb->iov, mh_.msg_iovlen);
 //dprintf("layer: %d \n",pb->layer);
-	transmit(pb);
+	transmit(pb, recv_by_ch);
 	loopback(pb);
 //	pb->release() is called by decoder in loopback;
 }
 
-void Transmitter::output_data_only(pktbuf* pb) 
+void Transmitter::output_data_only(pktbuf* pb, bool flag) 
 {
-	tx_data_only(pb);
+	tx_data_only(pb, flag);
 	loopback(pb);
 }
 

Modified: vic/branches/cc/rtp/transmitter.h
==============================================================================
--- vic/branches/cc/rtp/transmitter.h	(original)
+++ vic/branches/cc/rtp/transmitter.h	Sat Mar 27 06:02:11 2010
@@ -90,8 +90,9 @@
 	void flush();
 	void send(pktbuf*);
 	inline bool is_cc_on() { return is_cc_active_; }
-	virtual void cc_tfwc_output();
-	void cc_tfwc_output(pktbuf*);
+	virtual void cc_tfwc_output(bool recv_by_ch=0);
+	virtual void cc_tfwc_output(pktbuf*);
+	virtual void cc_tfwc_trigger(pktbuf*);
 	void cc_tfrc_output();
 
 	/*
@@ -107,19 +108,20 @@
 		return ((double) tv.tv_sec + 1e-6 * (double) tv.tv_usec);
 	}
 	double tx_now_offset_;
+	inline double tx_get_now() { return (tx_now()-tx_ts_offset()); }
 	virtual inline double tx_ts_offset() { return (tx_now_offset_); }
 
 	// Tx pktbuf size
-	int tx_buf_size();
+	virtual int tx_buf_size();
 
 protected:
 	void update(int nbytes);
 	void dump(int fd, iovec*, int iovel) const;
 	void loopback(pktbuf*);
-	void output(pktbuf* pb);
-	void output_data_only(pktbuf* pb);
-	virtual void transmit(pktbuf* pb) = 0;
-	virtual void tx_data_only(pktbuf* pb) = 0;
+	void output(pktbuf* pb, bool recv_by_ch=0);
+	void output_data_only(pktbuf* pb, bool flag);
+	virtual void transmit(pktbuf* pb, bool recv_by_ch=0) = 0;
+	virtual void tx_data_only(pktbuf* pb, bool flag) = 0;
 	double gettimeofday_secs() const;
 	double txtime(pktbuf* pb);
 
@@ -155,6 +157,18 @@
 	static buffer* freebufs_;
 	static int nbufs_;
 	static int nhdrs_;
+
+	// print banner
+	inline void cc_output_banner_top() {
+	fprintf(stderr,"\t--------entering cc_tfwc_output()-----------\n");
+	fprintf(stderr,"\t|                                          |\n");
+	fprintf(stderr,"\tV                                          V\n");
+	}
+	inline void cc_output_banner_bottom() {
+	fprintf(stderr,"\t^                                          ^\n");
+	fprintf(stderr,"\t|                                          |\n");
+	fprintf(stderr,"\t============================================\n");
+	}
 };
 
 #endif



More information about the Sumover-dev mailing list