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

sumover-dev at cs.ucl.ac.uk sumover-dev at cs.ucl.ac.uk
Fri Jun 12 14:14:24 BST 2009


Author: piers
Date: Fri Jun 12 14:14:21 2009
New Revision: 4466

Modified:
   vic/branches/cc/cc/tfwc_rcvr.cpp
   vic/branches/cc/cc/tfwc_rcvr.h
   vic/branches/cc/cc/tfwc_sndr.cpp
   vic/branches/cc/cc/tfwc_sndr.h
   vic/branches/cc/rtp/rtp.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:
rtp/session.[ch]*:
- Removed unnecessary malloc's - the RTCP pktbuf is already allocated - the RTCP-XR header struct is just cast to the appropriate point in the packet buffer.
- Moved cc_output() to rtp/transmitter.cpp - so it can be used in transmitter.cpp
- Updated the header fields conversions and changed chunk to be uint16_t (which matches the spec).

rtp/transmitter.[ch]*
- moved cc_output() here from session.cpp

cc/tfwc_*
Updated to match changes in header fields and chunks (now uint16_t)



Modified: vic/branches/cc/cc/tfwc_rcvr.cpp
==============================================================================
--- vic/branches/cc/cc/tfwc_rcvr.cpp	(original)
+++ vic/branches/cc/cc/tfwc_rcvr.cpp	Fri Jun 12 14:14:21 2009
@@ -55,14 +55,16 @@
 	currNumVec_(0),
 	prevNumVec_(0)
 {
-	tfwcAV = (u_int16_t *) malloc(sizeof(u_int16_t *));;
+	tfwcAV = (u_int16_t *) malloc(17);
+	bzero(tfwcAV,17);
 }
 
 void TfwcRcvr::tfwc_rcvr_recv(u_int16_t type, u_int16_t seqno, 
-				u_int32_t *chunk, int num_chunks) 
+				u_int16_t *chunk, int num_chunks) 
 {
 	// retrived ackofack
-	u_int16_t ackofack = chunk[num_chunks-1] >> 16;
+	//u_int16_t ackofack = chunk[num_chunks-1] >> 16;
+	u_int16_t ackofack = chunk[0];
 
 	// variables
 	int numLoss		= 0;	// number of packet loss count

Modified: vic/branches/cc/cc/tfwc_rcvr.h
==============================================================================
--- vic/branches/cc/cc/tfwc_rcvr.h	(original)
+++ vic/branches/cc/cc/tfwc_rcvr.h	Fri Jun 12 14:14:21 2009
@@ -42,7 +42,7 @@
 public:
 	TfwcRcvr();
 	void tfwc_rcvr_recv(u_int16_t type, u_int16_t seqno, 
-			u_int32_t *chunk, int num_chunks);
+			u_int16_t *chunk, int num_chunks);
 
 protected:
 	// AckVec clone

Modified: vic/branches/cc/cc/tfwc_sndr.cpp
==============================================================================
--- vic/branches/cc/cc/tfwc_sndr.cpp	(original)
+++ vic/branches/cc/cc/tfwc_sndr.cpp	Fri Jun 12 14:14:21 2009
@@ -120,7 +120,7 @@
  * main TFWC reception path
  */
 void TfwcSndr::tfwc_sndr_recv(u_int16_t type, u_int16_t begin, u_int16_t end,
-		u_int32_t *chunk, int num_chunks)
+		u_int16_t *chunk, int num_chunks)
 {
 	// retrieve ackvec
 	if (type == XR_BT_1) {
@@ -134,7 +134,7 @@
 		jacked_ = ends_ - 1;
 
 		// declared AckVec
-		ackv_ = (u_int16_t *) malloc (sizeof(u_int16_t) * num_chunks);
+		/*ackv_ = (u_int16_t *) malloc (sizeof(u_int16_t) * num_chunks);
 
 		// clone AckVec from Vic application
 		for (int i = 1; i <= num_chunks; i++) {
@@ -152,10 +152,10 @@
 			} else {
 				ackv_[i] = chunk[j] & 0x0000FFFF;
 			}
-		}
+		}*/
 
 		// generate seqno vec
-		//gen_seqvec(begins_, ends_, jacked_, ackv);
+		gen_seqvec(begins_, ends_, jacked_, chunk[0]);
 		print_seqvec(begins_, ends_);
 
 		// generate margin vector

Modified: vic/branches/cc/cc/tfwc_sndr.h
==============================================================================
--- vic/branches/cc/cc/tfwc_sndr.h	(original)
+++ vic/branches/cc/cc/tfwc_sndr.h	Fri Jun 12 14:14:21 2009
@@ -62,7 +62,7 @@
 
 	// main reception path (XR packet)
 	void tfwc_sndr_recv(u_int16_t type, u_int16_t begin, u_int16_t end,
-			u_int32_t *chunk, int num_chunks);
+			u_int16_t *chunk, int num_chunks);
 
 	// return current data packet's seqno
 	inline u_int16_t tfwc_sndr_get_seqno() { return seqno_; }
@@ -124,12 +124,13 @@
 	}
 	// generate seqno vector (interpret ackvec to real sequence numbers)
 	inline void gen_seqvec(u_int16_t begins, u_int16_t ends, 
-			u_int16_t hseq, u_int16_t vec) {
+			u_int16_t hseq, u_int16_t ackvec) {
 		int cnt = ends - begins;	// number of packets in ackvec
 		int offset = 0;				// if the bit is zero, then increment 
-		
+	
+		// ??? Doesn't take account of ackvec from more than one chunk
 		for (int i = 0; i < cnt; i++) {
-			if( CHECK_BIT_AT(vec, (cnt-i)) )
+			if( CHECK_BIT_AT(ackvec, (cnt-i)) )
 				seqvec_[(i-offset)%SSZ] = hseq - i;
 			else
 				offset++;

Modified: vic/branches/cc/rtp/rtp.h
==============================================================================
--- vic/branches/cc/rtp/rtp.h	(original)
+++ vic/branches/cc/rtp/rtp.h	Fri Jun 12 14:14:21 2009
@@ -149,13 +149,25 @@
 #define XR_BT_4	0x04	// Receiver Reference Time Report Block
 struct rtcp_xr {
 	// extended report block header
-	u_int16_t xr_flags;	/* BT:8 TS:8 */
+	u_int8_t BT;	  /* Block Type */
+	u_int8_t xr_flag;	  /* xr_flag */
+	u_int16_t xr_len;	/* XR report block length (in bytes)*/
+};
+
+struct rtcp_xr_BT_1_hdr {
+	u_int8_t BT;	  /* Block Type */
+    struct {
+	    u_int8_t rsvd:4; /* Reserved field */
+	    u_int8_t T:4;	  /* Thinning flag */
+	} xr_flags;	
+
 	u_int16_t xr_len;	/* XR report block length (in bytes)*/
 	// type-specific block contents
-	//u_int32_t ssrc;/* ssrc of the RTP data pkt being reported upon by this */
-	//u_int16_t begin_seq; /* first seqno that this block report */
-	//u_int16_t end_seq;	/* last seqno that this block report plus 1 */
-	//u_int16_t chunk;	/* extended report chunks */
+	u_int32_t ssrc;/* ssrc of the RTP data pkt being reported upon by this */
+	u_int16_t begin_seq; /* first seqno that this block report */
+	u_int16_t end_seq;	/* last seqno that this block report plus 1 */
+	//u_int16_t chunk1;	/* extended report chunks */
+	//u_int16_t chunk2;	/* extended report chunks */
 };
 
 #define RTCP_PT_SR	200	/* sender report */

Modified: vic/branches/cc/rtp/session.cpp
==============================================================================
--- vic/branches/cc/rtp/session.cpp	(original)
+++ vic/branches/cc/rtp/session.cpp	Fri Jun 12 14:14:21 2009
@@ -649,8 +649,10 @@
 	// set RTCP flag to XR packet
 	flags |= RTCP_PT_XR;
 
+	debug_msg("about to send RTCP XR\n");
+
 	// declare XR packet
-	rtcp_xr* xr = (rtcp_xr*)(rh + 1);
+	rtcp_xr_BT_1_hdr* xr = (rtcp_xr_BT_1_hdr*)(rh + 1);
 
 	// number of XR block contents (initialization)
 	int num_ssrc;	// number of ssrc entry
@@ -668,35 +670,43 @@
 	if (am_i_sender()) {
 		// this block is used for giving seqno and ackofack
 		if(bt == XR_BT_1) {
+	debug_msg("about to send RTCP XR 1\n");
 			// number of block entries
-			num_ssrc = 1;
-			num_begins = 1;
-			num_ends = 1;
+			//num_ssrc = 1;
+			//num_begins = 1;
+			//num_ends = 1;
 			num_chunks = 1;
 
 			// set XR block flags (block type and length)
-			xr->xr_flags = htons(XR_BT_1 << 8);
+			//xr->xr_flags = htons(XR_BT_1 << 8);
+			xr->BT = XR_BT_1;
+			xr->xr_flags.rsvd = 0x00;
+			xr->xr_flags.T = 0x00;
 
 			// allocate report block in memory
-			rb = (u_char *) malloc(sizeof(xr) + num_ssrc 
-					+ num_begins + num_ends + num_chunks);
+			//rb = (u_char *) malloc(sizeof(xr) + num_ssrc*4 
+			//		+ (num_begins + num_ends + num_chunks)*2);
 
 			// set report block entry pointer
-			u_int32_t *ent = (u_int32_t *) (sizeof(xr) + rb);
+			//rtcp_xr_BT_1_hdr *ent = (rtcp_xr_BT_1_hdr *) (sizeof(xr) + rb);
 
 			// ssrc of XR source (currently unused)
-			xrssrc = 0; ent[0] = xrssrc;
+			xrssrc = 255; 
+			//ent[0] = xrssrc;
+			xr->ssrc = htonl(xrssrc);
 
 			// get current RTP data packet seqno from TfwcSndr
-			ent[1] = 0;
-			ent[1] |= htons(tfwc_sndr_get_seqno());
-			ent[1] <<= 16;
-			ent[1] |= htons(tfwc_sndr_get_seqno() + 1);
+			//ent[1] = 0; ent[1] |= htons(tfwc_sndr_get_seqno());
+			xr->begin_seq = htons(tfwc_sndr_get_seqno());
+			//ent[1] <<= 16; ent[1] |= htons(tfwc_sndr_get_seqno() + 1);
+			xr->end_seq = htons(tfwc_sndr_get_seqno() + 1);
 
+			debug_msg("Sending beg_seq: %d, end: %d\n",ntohs(xr->begin_seq),ntohs(xr->end_seq) );
+			
 			// set ack of ack
-			ent[2] = 0;
-			ent[2] |= htons(tfwc_sndr_get_aoa());
-			ent[2] <<= 16;
+			//ent[2] = 0; ent[2] |= htons(tfwc_sndr_get_aoa()); ent[2] <<= 16;
+			u_int16_t *chunks = (u_int16_t *) (xr + 1);
+			chunks[0] = htons(tfwc_sndr_get_aoa());
 
 			//debug_msg("	SeqNo:		%d\n", tfwc_sndr_get_seqno());
 		}
@@ -709,53 +719,41 @@
 		// this block is used for giving ackvec
 		if (bt == XR_BT_1) {
 			// number of block entries
-			num_ssrc = 1;
-			num_begins = 1;
-			num_ends = 1;
+			//num_ssrc = 1;
+			//num_begins = 1;
+			//num_ends = 1;
 
 			// set XR block type
-			xr->xr_flags = htons(XR_BT_1 << 8);
+			//xr->xr_flags = htons(XR_BT_1 << 8);
+			xr->BT = XR_BT_1;
 
 			// number of AckVec array
 			num_chunks = tfwc_rcvr_numvec();
+			if (num_chunks<1) num_chunks=1;
 
 			// allocate report block in memory
-			rb = (u_char *) malloc(sizeof(xr) + num_ssrc 
-					+ num_begins + num_ends + num_chunks);
+			//rb = (u_char *) malloc(sizeof(xr) + num_ssrc 
+			//		+ num_begins + num_ends + num_chunks);
 
 			// set report block entry pointer
-			u_int32_t *ent = (u_int32_t *) (sizeof(xr) + rb);
+			//u_int32_t *ent = (u_int32_t *) (sizeof(xr) + rb);
 
 			// ssrc of XR source (currently unused)
 			xrssrc = 0;
-			ent[0] = xrssrc;
+			//ent[0] = xrssrc;
+			xr->ssrc = htonl(xrssrc);
 
 			// begin/end for AckVec
-			ent[1] = 0;
-			ent[1] |= htons(tfwc_rcvr_begins());
-			ent[1] <<= 16;
-			ent[1] |= htons(tfwc_rcvr_ends());
+			//ent[1] = 0; ent[1] |= htons(tfwc_rcvr_begins());
+        	xr->begin_seq = htons(tfwc_rcvr_begins());
+			//ent[1] <<= 16; ent[1] |= htons(tfwc_rcvr_ends());
+			xr->end_seq = htons(tfwc_rcvr_ends());
 
 			// clone AckVec from TfwcRcvr
-			for (int i = 1; i <= num_chunks; i++) {
-				bool odd = true;
-				int j = i/2 + 1;
-
-				if (i%2 == 0) {
-					odd = false;
-					j -= 1;
-				}
-
-				// clone AckVec array to chunk entry
-				if(odd) {
-					// odd number chunk
-					ent[j+1] = 0;	// initialize
-					ent[j+1] |= htons(tfwc_rcvr_getvec(i-1));
-				} else {
-					// even number chunk
-					ent[j+1] <<= 16; // left-shift first
-					ent[j+1] |= htons(tfwc_rcvr_getvec(i-1));
-				}
+			u_int16_t *chunks = (u_int16_t *) (xr + 1);
+
+			for (int i = 0; i <= num_chunks; i++) {
+				chunks[i] = htons(tfwc_rcvr_getvec(i));
 			}
 		}
 		else if (bt == XR_BT_3) {
@@ -763,17 +761,20 @@
 		} 
 	} // end of if (am_i_sender())
 
-	++xr;
+	//++xr;
 
-	// XR report block length
-	int xrlen = sizeof(xr);
+	// XR report block length in bytes
+	int xrlen = sizeof(rtcp_xr_BT_1_hdr) + num_chunks*2;
+	// Convert XR report block length to multiples of 32 bit-words minus 1
 	xr->xr_len = htons((xrlen >> 2) - 1);
 
 	// RTCP header flags (this is not the XR header flags)
 	rh->rh_flags = htons(flags);
 
 	// RTCP packet length
-	int len = (u_char *) xr - pktbuf_;	
+	int len = (u_char *) ++xr + num_chunks*2 - pktbuf_;	
+	debug_msg("RTCP XR: len: %d, xrlen=%d\n", len, xrlen);
+	len = sizeof(rtcphdr) + sizeof(rtcp_xr_BT_1_hdr) + num_chunks*2;
 	rh->rh_len = htons((len >> 2) - 1);
 
 	// send XR report block
@@ -1239,61 +1240,74 @@
 void SessionManager::parse_xr_records(u_int32_t ssrc, rtcp_xr* xr, int cnt,
 				const u_char* ep, Address & addr)
 {
-	//printf("\tentering parse_xr_records()\n");
+	printf("\tentering parse_xr_records()\n");
+	rtcp_xr_BT_1_hdr *xr1;
 	UNUSED(ssrc);
 	UNUSED(cnt);
 	UNUSED(ep);
 	UNUSED(addr);
 
-	// XR block flags and length
-	u_int16_t flags = xr->xr_flags;
-	u_int16_t xrlen	= xr->xr_len;
+	// XR block length
+	u_int16_t xrlen	= ntohs(xr->xr_len);
 
 	// XR repport block
-	u_int32_t *rb = (u_int32_t *) malloc(xrlen);
+	//u_int32_t *rb = (u_int32_t *) malloc(xrlen);
 	
-	// parse XR information (xrssrc, begin, end)
-	u_int32_t xrssrc = rb[0]; UNUSED(xrssrc);
-	u_int16_t begin = rb[1] >> 16;
-	u_int16_t end = rb[1] & 0x0000FFFF;
-
-	// declare chunks
-	int num_chunks = 0; 
-	u_int32_t *chunk;
-
-	num_chunks = xrlen - 3;	
-	chunk = (u_int32_t *) malloc(sizeof(u_int32_t) * num_chunks);
+	if ( xr->BT == XR_BT_1 ) {
+	  xr1 = ( rtcp_xr_BT_1_hdr *) xr;
 
-	// parse chunks information (AckVec)
-	for (int i = 0; i < num_chunks; i++)
-		chunk[i] = rb[i+2];
-
-	// i am an RTP data sender, so do the sender stuffs
-	if (am_i_sender()) {
-		// parse XR chunks
-		tfwc_sndr_recv(flags, begin, end, chunk, num_chunks);
-		// we need to call Transmitter::output(pb) to make Ack driven
-		cc_output();
-	}
-	// i am an RTP data receiver, so do the receiver stuffs
-	else {
-		// parse XR chunks
-		tfwc_rcvr_recv(flags, begin, chunk, num_chunks);
-		// send receiver side XR report
-		ch_[0].send_ackv();
-		//ch_[0].send_ts_echo();
-	}
+	  // parse XR information (xrssrc, begin, end)
+	  u_int32_t xrssrc = ntohl(xr1->ssrc); UNUSED(xrssrc);
+	  u_int16_t begin = ntohs(xr1->begin_seq);
+	  u_int16_t end = ntohs(xr1->end_seq);
+
+	  // declare chunks
+	  int num_chunks = 0; 
+	  u_int16_t *chunk = (u_int16_t *) ++xr1;
+
+	  // num_chunks = xrlen - sizeof(xr_BT_1_hr)[=3] + 1(countering -1 in hdr calc)
+	  num_chunks = (xrlen - 2)*2;	
+	  //chunk = (u_int32_t *) malloc(sizeof(u_int32_t) * num_chunks);
+
+	  // parse chunks information (AckVec)
+	  //for (int i = 0; i < num_chunks; i++)
+	  //	chunk[i] = rb[i+2];
+
+	  // i am an RTP data sender, so do the sender stuffs
+	  if (am_i_sender()) {
+		  // parse XR chunks
+		  printf("\tparse_xr - i_am_sender \n");
+		  tfwc_sndr_recv(xr->BT, begin, end, chunk, num_chunks);
+		  // we need to call Transmitter::output(pb) to make Ack driven
+		  cc_output();
+	  }
+	  // i am an RTP data receiver, so do the receiver stuffs
+	  else {
+		  // parse XR chunks
+		  tfwc_rcvr_recv(xr->BT, begin, chunk, num_chunks);
+		  // send receiver side XR report
+		  ch_[0].send_ackv();
+		  //ch_[0].send_ts_echo();
+	  }
+	} else 
+	  debug_msg("UNKNOWN RTCP-XR packet:BT:%d\n",xr->BT);
 }
 
-void SessionManager::cc_output() 
+/*void SessionManager::cc_output() 
 {
 	printf("\tentering cc_output()\n");
 	pktbuf* pb = head_;	// head of the packet queue
 	rtphdr* rh;		// declare rtp header
 
 	// if pb is not 0, then parse rtp header 
-	if (pb != 0) 
-		rh = (rtphdr *) pb->data;
+	if (pb == 0) {
+	  is_first_ = true;
+	  return; 
+	}
+
+	printf("\tThere is a packet available to send cc_output()\n");
+
+	rh = (rtphdr *) pb->data;
 
 	// cwnd value
 	int magic = (int) tfwc_magic();
@@ -1326,7 +1340,7 @@
 		} else 
 			break;
 	} // end while
-}
+}*/
 
 void CtrlHandler::send_ackv()
 {

Modified: vic/branches/cc/rtp/session.h
==============================================================================
--- vic/branches/cc/rtp/session.h	(original)
+++ vic/branches/cc/rtp/session.h	Fri Jun 12 14:14:21 2009
@@ -143,7 +143,7 @@
 	void build_ts_pkt(CtrlHandler* ch);
 	void build_ackv_pkt(CtrlHandler* ch);
 	void build_ts_echo_pkt(CtrlHandler* ch);
-	void cc_output();
+	//void cc_output();
 
 	// am i a data sender?
 	inline bool am_i_sender() { return is_sender_; }

Modified: vic/branches/cc/rtp/transmitter.cpp
==============================================================================
--- vic/branches/cc/rtp/transmitter.cpp	(original)
+++ vic/branches/cc/rtp/transmitter.cpp	Fri Jun 12 14:14:21 2009
@@ -218,8 +218,16 @@
 	if (is_cc_on()) {
 		// if it is the very first packet, just send it.
 		if(is_first_) {
-			tfwc_sndr_send(pb);
-			output(pb);
+			//tfwc_sndr_send(pb);
+			//debug_msg("sending RTP packet\n");
+			//output(pb);
+			if (head_ != 0) {
+				tail_->next = pb;
+				tail_ = pb;
+			} else
+				tail_ = head_ = pb;
+			pb->next = 0;
+			cc_output();
 			is_first_ = false;
 		} 
 		// if it is not, just queue up the packets.
@@ -255,6 +263,57 @@
 	} // if (is_cc_active_)
 }
 
+void Transmitter::cc_output()
+{
+    printf("\tentering cc_output()\n");
+    pktbuf* pb = head_; // head of the packet queue
+    rtphdr* rh;     // declare rtp header
+
+    // if pb is not 0, then parse rtp header 
+    if (pb == 0) {
+      is_first_ = true;
+      return;
+    }
+
+    printf("\tThere is a packet available to send cc_output()\n");
+
+    rh = (rtphdr *) pb->data;
+
+    // cwnd value
+    int magic = (int) tfwc_magic();
+    debug_msg("cwnd: %d\n", magic);
+
+    // just acked seqno
+    int jack = (int) tfwc_sndr_jacked();
+    debug_msg("jack: %d\n", jack);
+
+    debug_msg("seqno: %d\n", ntohs(rh->rh_seqno));
+    // while packet seqno is within "cwnd + jack", send that packet
+    while (ntohs(rh->rh_seqno) <= magic + jack) {
+        debug_msg("Sending RTP pkt seqno: %d\n", ntohs(rh->rh_seqno));
+        // record seqno and timestamp at TfwcSndr side
+        tfwc_sndr_send(pb);
+
+        // declare the next packet
+        pktbuf* nx = pb->next;
+
+        // call Transmitter::output(pb)
+        output(pb);
+
+        // move packet pointer
+        pb = nx;
+
+        // if pb is not 0, 
+        // then move head pointer and parse rtp header
+        if (pb != 0) {
+            head_ = pb;
+            rh = (rtphdr *) pb->data;
+        } else {
+            break;
+		}
+    } // end while
+}
+
 void Transmitter::timeout()
 {
 	double now = gettimeofday_secs();

Modified: vic/branches/cc/rtp/transmitter.h
==============================================================================
--- vic/branches/cc/rtp/transmitter.h	(original)
+++ vic/branches/cc/rtp/transmitter.h	Fri Jun 12 14:14:21 2009
@@ -86,6 +86,7 @@
 	void flush();
 	void send(pktbuf*);
 	inline bool is_cc_on() { return is_cc_active_; }
+	void cc_output();
 
 	/*
 	 * Buffer allocation hooks.



More information about the Sumover-dev mailing list