Congestion Control for Real-time Interactive Applications -  Google summer of Code 2008 project

Subversion branch

A branch has been created to provide for the work on:

svn co vic-cc


Vic uses the UCL common library. You can check out the source code at our SVN server as described at  here.

svn co common

Vic also uses Tcl/Tk development libraries, so either you can use the UCL Tcl/Tk branch or you could install Tcl/Tk development files depending on your systems. So, for example, if you are using Debian/Ubuntu, then you could install Tcl/Tk 8.5 development files in your system as belows.

sudo aptitude install tcl8.5-dev tk8.5-dev

In summary,

  • make a directory, e.g., AVATS
  • check out the UCL common library in AVATS directory
  • check out Vic CC code in AVATS directory
  • compile UCL common library first and then compile Vic CC

Draft plan and design

A short note on planning the GSoC project has been update. (May 30, 2008)


(Jul. 22, 2008)

  • Modifying the transmitter/network object to provide the hooks for congestion control
  • Add the ACK vector field to send buffer
  • Receiver side mechanisms - Sequenced number ACK'ing
  • Adding TFWC algorithm
    • ACK clocked delivery
    • Loss interval
    • RTT
  • Feedback mechanism for TFWC window to codec rate control
  • Complete prototype initial testing [31/7/08]

Brief descriptions on TFWC over vic

The TFWC mechanism runs over two different channels: RTP data channel and RTCP control channel. The data packets are conveyed over RTP data channel and the TFWC control information (e.g., AckVec) is conveyed over RTCP control channel. As the TFWC control message needs to be delivered by the control channel, we have used the extended RTCP (RTCP XR) packet block to exchange this information. The RTCP XR is defined at  RFC 3611. Particularly, we have used XR block type 1 when we exchange AckVec between sender and receiver.

Data Sender

Upon every AckVec reception, the data sender will compute the congestion window (cwnd) using TFWC algorithm and if the next data packet can be sent (for example, if the next available packet's sequence number is less than or equal to (cwnd + unacked packet seqno), then it send out this packet.) When it sends out a data packet, it also sends an XR packet containing "seqno and ackofack" information.

Data Receiver

Upon every XR report reception, the receiver will parse the XR information (e.g., packet seqno and ackofack) and build AckVec. And, it generates an XR containing this AckVec information and sends it back to the sender.

Ack Driven

When the data sender gets an XR from the data receiver, it parses the AckVec information and sends out a data packet depending upon the rule as in the above (i.e., seqno <= cwnd + unacked), hence making it Ack driven.

Code level descriptions on TFWC over vic

Working flows

For the very first data packet, it is just sent out without checking anything else. When doing this, an XR packet is also sent right away containing that packet's seqno and ackofack (which is 1 and 0, respectively, at this round) - this is implemented in Transmitter::send(). It is just to trigger sending packets in the data sender side. Later on, the data sender will send an XR packet when it sends out every data packet. So, in short, whenever the data sender calls SessionManager::transmit() to send a data packet, it will also call SessionManager::send_xreport(). In this way, the XR packet will convey control information associated with the data packet.

At the receiver, whenever it gets an XR packet, it will call SessionManager::recv(CtrlHandler*) and eventually this will call SessionManager::parse_xr_records(). Then, the receiver will retrieve the packet __seqno__ and __ackofack__ information from it, and it will build AckVec based upon the sequence number it has received. Right after building up the AckVec, it will send this information using XR report by calling SessionManager::send_xreport_back().

flow diagram at sender

(Upon AckVec reception)

SessionManager::parse_xr_records() (get AckVec) -> SessionManager::cc_output() (check if the packet can be sent) -> Transmitter:output() -> SessionManager::transmit() (send a data packet and an XR packet) -> SessionManager::send_xreport()

flow diagram at receiver

(Upon an XR reception)

SessionManager::recv(CtrlHandler *) -> SessionManager::parse_xr_records() (get seqno and ackofack) -> SessionManager::send_xreport_back()


The video traffic can be tested by running:

./vic -XstillGrabber <ip address>/<port number>

We have extended the still grabber so that it can take a pre-recorded video frames (YUV format). So, we can test this video stream by downloading one of the popular sequences such as foreman.yuv (a simple Google will turn up many location to get it).

For example, in order to test between two machines:

foo% ./vic bar/9090
bar% ./vic foo/9090

Google Summer of Code Source Code Submission

The Google Summer of Code (GSoC) 2008 has officially ended and the code submission can be downloaded at However, this code submission is a snapshot version which only includes the work done by the 18th of August, 2008. Therefore, if you want to install the fresh copy of the source code, it is recommended to check out the code in our subversion branch as described at the top of this page.

Project Plan for October 2008 until December 2008

The prototype implementation of TFWC is getting finished, and the validation test over HEN would be the next step. This would include testing TFWC protocol functionalities over various network settings (e.g., different parameter settings for the bottleneck queue length, the bottleneck queue discipline, the bottleneck network link speed with different link delay, and the different types of sources, etc). Once we complete the TFWC validation test, we would change codec's target rate on the fly as the TFWC provides useful information.

After that, we will implement TFRC over vic - we are currently aiming at implementing it as a sender-driven TFRC as opposed to a receiver-driven. This is because we already have a sender-driven TFWC framework and it would be easier to extend it to TFRC. Also, in this way, it could be a direct comparison between TFWC and TFRC. However, if we want to consider it deploying over multicast networks, then we will have to re-think this strategy.

We are aiming that the draft-version of the implementation would be done by the end of the year 2008.

Work in Progress

  • In SessionManager::cc_output() method, it seems that the current packet's sequence number is pointing to a wrong one all the times - need to be examined carefully soon. (This has been verified that cc_output() method is working fine as of the 13th of November, 2008. See svn log message r4314 in cc branch.)
  • In rtp/session.[h,cpp], we implemented a mechanism to check if this is a data sender or a receiver. We declared a global variable is_sender_ at the top of rtp/session.h and utilised it in a various locations.
  • Look into TfwcSndr::tfwc_sndr_recv() method in cc/tfwc_sndr.cpp.
    • Verify AckVec trimming mechanism
    • Examine loss detection mechanism
  • TFWC unit test code implementation
  • We are currently changing the RTP XR packet format that can more comply to the standard (RFC 3611).
  • Write up HEN experiment scenarios
    • various network parameter settings (similar to the ones used with ns-2 simulations)
    • interaction with codecs
  • TFRC (sender driven) implementation
  • Resetting Tfwc timer issue
    • We need to reset the timer when we see a packet loss which initiates a new loss event. If we don't do this, we may end up seeing a bunch of timer-out even if when the loss rate is fairly low (e.g., p = 0.01).
  • All of the above work items have been successfully done as of 2010 May, and we are currently at the last minute doing experiments comparing TFWC/TFRC Cc mechanisms over Vic using H.261 codec.


Developer's Mailing List