Sunday, December 29, 2013

Pacing, Pading and AutoMuter

In the last months those terms have been appearing often in the WebRTC codebase and discussions.  In this post I will try to give a very brief description of the meaning, behaviour and implementation status, and attach some comments or source code that can be helpful to illustrate those features.  

Pacing or Smoothing
When transmitting video it is common to have peaks of traffic when sending a video frame because it is consisting on lots of RTP packets (from 1 to even 50 in case of a key frame) that are sent in the same instant of time.   The solution to alleviate that problem is to add some spacing between those packets or even between frames if needed.    This is known as pacing or smoothing and in case of the Google WebRTC implementation it is enabled by default in the latests versions. 

  // Set the pacing target bitrate and the bitrate up to which we are allowed to
  // pad. We will send padding packets to increase the total bitrate until we
  // reach |pad_up_to_bitrate_kbps|. If the media bitrate is above
  // |pad_up_to_bitrate_kbps| no padding will be sent.

The bitrate during a videoconference can be very dynamic, for example being very low if the camera is pointing to a wall and increasing inmediatelly if a person starts moving.    This behaviour can be a problem with networks that take some time to adapt changes in traffic (specially mobile networks) and can be alleviated by keeping a constant bitrate by sending fake packets when there is no enough actual data to maintain that bitrate.   This is very easy to do by using RTP padding with random data but can be done even better by adding redundancy or retransmissions so that those packets can convey useful information in case of packet loss.

 int RTPSender::BuildPaddingPacket(uint8_t* packet, int header_length,
                                   int32_t bytes) {
   int padding_bytes_in_packet = kMaxPaddingLength;
   if (bytes < kMaxPaddingLength) {
     padding_bytes_in_packet = bytes;
   packet[0] |= 0x20;
   // Set padding bit.
   int32_t *data = reinterpret_cast(&(packet[header_length]));
   // Fill data buffer with random data.
   for (int j = 0; j < (padding_bytes_in_packet >> 2); ++j) {
     data[j] = rand();  // NOLINT
   // Set number of padding bytes in the last byte of the packet.
   packet[header_length + padding_bytes_in_packet - 1] = padding_bytes_in_packet;
   return padding_bytes_in_packet;

Suspend Below MinBitrate or AutoMuter 
Under some network situations it is not possible to offer a good video quality and it is better to completely disable the video and keep only the audio stream.   This can be decided based on the bitrate estimation (that is usually calculated using packet loss and REMB packets) when it goes below or above a threshold (this threshold is the minimum bitrate for that codec and can be around 50Kps in a default WebRTC endpoint).  This is partially implemented but not yet activated in WebRTC browsers. 

 void MediaOptimization::CheckSuspendConditions() {  
   // Check conditions for SuspendBelowMinBitrate. |target_bit_rate_| is in bps.  
   if (suspension_enabled_) {
     if (!video_suspended_) {
       // Check if we just went below the threshold.      
       if (target_bit_rate_ < suspension_threshold_bps_) {
         video_suspended_ = true;
     } else {
       // Video is already suspended. Check if we just went over the threshold
       // with a margin.
       if (target_bit_rate_ > suspension_threshold_bps_ + suspension_window_bps_) {
         video_suspended_ = false;

Thursday, December 12, 2013

OpenH264 Cisco code released

Finally Cisco has released the source code of the announced open source H.264 implementation:

Code looks promising although still work in progress (not every platform supported yet) and the features included in encoder and decoder are impressive (simulcast, resolution, quality adaptation...).

The binary module (the compiled version of that code) is not yet available, but apparently Mozilla could be already working on the integration in Firefox.

This is a great video explaining how is this code and binary module going to work and the implications of that behavior:

These are obviously good news although I still disagree on the inclusion of H.264 as mandatory to implement codec for WebRTC.  The web can not be based on technologies requiring royalties to be used even if Cisco is generous to pay for it for some platforms during some amount of time.

BTW, I still maintain my bet of not having a MTI codec in WebRTC.