[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