Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / media / base / mediachannel.h
index 919248f..3759acc 100644 (file)
 #include <string>
 #include <vector>
 
-#include "talk/base/basictypes.h"
-#include "talk/base/buffer.h"
-#include "talk/base/dscp.h"
-#include "talk/base/logging.h"
-#include "talk/base/sigslot.h"
-#include "talk/base/socket.h"
-#include "talk/base/window.h"
 #include "talk/media/base/codec.h"
 #include "talk/media/base/constants.h"
 #include "talk/media/base/streamparams.h"
+#include "webrtc/base/basictypes.h"
+#include "webrtc/base/buffer.h"
+#include "webrtc/base/dscp.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/sigslot.h"
+#include "webrtc/base/socket.h"
+#include "webrtc/base/window.h"
 // TODO(juberti): re-evaluate this include
 #include "talk/session/media/audiomonitor.h"
 
-namespace talk_base {
+namespace rtc {
 class Buffer;
 class RateLimiter;
 class Timing;
 }
 
-namespace webrtc {
-struct DataChannelInit;
-}
-
 namespace cricket {
 
 class AudioRenderer;
@@ -66,6 +62,7 @@ class VideoRenderer;
 const int kMinRtpHeaderExtensionId = 1;
 const int kMaxRtpHeaderExtensionId = 255;
 const int kScreencastDefaultFps = 5;
+const int kHighStartBitrate = 1500;
 
 // Used in AudioOptions and VideoOptions to signify "unset" values.
 template <class T>
@@ -107,7 +104,7 @@ class Settable {
   }
 
   std::string ToString() const {
-    return set_ ? talk_base::ToString(val_) : "";
+    return set_ ? rtc::ToString(val_) : "";
   }
 
   bool operator==(const Settable<T>& o) const {
@@ -172,6 +169,7 @@ struct AudioOptions {
     adjust_agc_delta.SetFrom(change.adjust_agc_delta);
     experimental_agc.SetFrom(change.experimental_agc);
     experimental_aec.SetFrom(change.experimental_aec);
+    experimental_ns.SetFrom(change.experimental_ns);
     aec_dump.SetFrom(change.aec_dump);
     tx_agc_target_dbov.SetFrom(change.tx_agc_target_dbov);
     tx_agc_digital_compression_gain.SetFrom(
@@ -184,6 +182,7 @@ struct AudioOptions {
     recording_sample_rate.SetFrom(change.recording_sample_rate);
     playout_sample_rate.SetFrom(change.playout_sample_rate);
     dscp.SetFrom(change.dscp);
+    opus_fec.SetFrom(change.opus_fec);
   }
 
   bool operator==(const AudioOptions& o) const {
@@ -198,6 +197,7 @@ struct AudioOptions {
         conference_mode == o.conference_mode &&
         experimental_agc == o.experimental_agc &&
         experimental_aec == o.experimental_aec &&
+        experimental_ns == o.experimental_ns &&
         adjust_agc_delta == o.adjust_agc_delta &&
         aec_dump == o.aec_dump &&
         tx_agc_target_dbov == o.tx_agc_target_dbov &&
@@ -208,7 +208,8 @@ struct AudioOptions {
         rx_agc_limiter == o.rx_agc_limiter &&
         recording_sample_rate == o.recording_sample_rate &&
         playout_sample_rate == o.playout_sample_rate &&
-        dscp == o.dscp;
+        dscp == o.dscp &&
+        opus_fec == o.opus_fec;
   }
 
   std::string ToString() const {
@@ -226,6 +227,7 @@ struct AudioOptions {
     ost << ToStringIfSet("agc_delta", adjust_agc_delta);
     ost << ToStringIfSet("experimental_agc", experimental_agc);
     ost << ToStringIfSet("experimental_aec", experimental_aec);
+    ost << ToStringIfSet("experimental_ns", experimental_ns);
     ost << ToStringIfSet("aec_dump", aec_dump);
     ost << ToStringIfSet("tx_agc_target_dbov", tx_agc_target_dbov);
     ost << ToStringIfSet("tx_agc_digital_compression_gain",
@@ -238,6 +240,7 @@ struct AudioOptions {
     ost << ToStringIfSet("recording_sample_rate", recording_sample_rate);
     ost << ToStringIfSet("playout_sample_rate", playout_sample_rate);
     ost << ToStringIfSet("dscp", dscp);
+    ost << ToStringIfSet("opus_fec", opus_fec);
     ost << "}";
     return ost.str();
   }
@@ -262,6 +265,7 @@ struct AudioOptions {
   Settable<int> adjust_agc_delta;
   Settable<bool> experimental_agc;
   Settable<bool> experimental_aec;
+  Settable<bool> experimental_ns;
   Settable<bool> aec_dump;
   // Note that tx_agc_* only applies to non-experimental AGC.
   Settable<uint16> tx_agc_target_dbov;
@@ -274,6 +278,8 @@ struct AudioOptions {
   Settable<uint32> playout_sample_rate;
   // Set DSCP value for packet sent from audio channel.
   Settable<bool> dscp;
+  // Set Opus FEC
+  Settable<bool> opus_fec;
 };
 
 // Options that can be applied to a VideoMediaChannel or a VideoMediaEngine.
@@ -281,10 +287,17 @@ struct AudioOptions {
 // We are moving all of the setting of options to structs like this,
 // but some things currently still use flags.
 struct VideoOptions {
+  enum HighestBitrate {
+    NORMAL,
+    HIGH,
+    VERY_HIGH
+  };
+
   VideoOptions() {
     process_adaptation_threshhold.Set(kProcessCpuThreshold);
     system_low_adaptation_threshhold.Set(kLowSystemCpuThreshold);
     system_high_adaptation_threshhold.Set(kHighSystemCpuThreshold);
+    unsignalled_recv_stream_limit.Set(kNumDefaultUnsignalledVideoRecvStreams);
   }
 
   void SetAll(const VideoOptions& change) {
@@ -294,16 +307,21 @@ struct VideoOptions {
     adapt_view_switch.SetFrom(change.adapt_view_switch);
     video_adapt_third.SetFrom(change.video_adapt_third);
     video_noise_reduction.SetFrom(change.video_noise_reduction);
-    video_three_layers.SetFrom(change.video_three_layers);
     video_one_layer_screencast.SetFrom(change.video_one_layer_screencast);
     video_high_bitrate.SetFrom(change.video_high_bitrate);
-    video_watermark.SetFrom(change.video_watermark);
+    video_start_bitrate.SetFrom(change.video_start_bitrate);
     video_temporal_layer_screencast.SetFrom(
         change.video_temporal_layer_screencast);
-    video_temporal_layer_realtime.SetFrom(
-        change.video_temporal_layer_realtime);
     video_leaky_bucket.SetFrom(change.video_leaky_bucket);
+    video_highest_bitrate.SetFrom(change.video_highest_bitrate);
     cpu_overuse_detection.SetFrom(change.cpu_overuse_detection);
+    cpu_underuse_threshold.SetFrom(change.cpu_underuse_threshold);
+    cpu_overuse_threshold.SetFrom(change.cpu_overuse_threshold);
+    cpu_underuse_encode_rsd_threshold.SetFrom(
+        change.cpu_underuse_encode_rsd_threshold);
+    cpu_overuse_encode_rsd_threshold.SetFrom(
+        change.cpu_overuse_encode_rsd_threshold);
+    cpu_overuse_encode_usage.SetFrom(change.cpu_overuse_encode_usage);
     conference_mode.SetFrom(change.conference_mode);
     process_adaptation_threshhold.SetFrom(change.process_adaptation_threshhold);
     system_low_adaptation_threshhold.SetFrom(
@@ -311,8 +329,14 @@ struct VideoOptions {
     system_high_adaptation_threshhold.SetFrom(
         change.system_high_adaptation_threshhold);
     buffered_mode_latency.SetFrom(change.buffered_mode_latency);
-    lower_min_bitrate.SetFrom(change.lower_min_bitrate);
     dscp.SetFrom(change.dscp);
+    suspend_below_min_bitrate.SetFrom(change.suspend_below_min_bitrate);
+    unsignalled_recv_stream_limit.SetFrom(change.unsignalled_recv_stream_limit);
+    use_simulcast_adapter.SetFrom(change.use_simulcast_adapter);
+    screencast_min_bitrate.SetFrom(change.screencast_min_bitrate);
+    use_improved_wifi_bandwidth_estimator.SetFrom(
+        change.use_improved_wifi_bandwidth_estimator);
+    use_payload_padding.SetFrom(change.use_payload_padding);
   }
 
   bool operator==(const VideoOptions& o) const {
@@ -322,14 +346,20 @@ struct VideoOptions {
         adapt_view_switch == o.adapt_view_switch &&
         video_adapt_third == o.video_adapt_third &&
         video_noise_reduction == o.video_noise_reduction &&
-        video_three_layers == o.video_three_layers &&
         video_one_layer_screencast == o.video_one_layer_screencast &&
         video_high_bitrate == o.video_high_bitrate &&
-        video_watermark == o.video_watermark &&
+        video_start_bitrate == o.video_start_bitrate &&
         video_temporal_layer_screencast == o.video_temporal_layer_screencast &&
-        video_temporal_layer_realtime == o.video_temporal_layer_realtime &&
         video_leaky_bucket == o.video_leaky_bucket &&
+        video_highest_bitrate == o.video_highest_bitrate &&
         cpu_overuse_detection == o.cpu_overuse_detection &&
+        cpu_underuse_threshold == o.cpu_underuse_threshold &&
+        cpu_overuse_threshold == o.cpu_overuse_threshold &&
+        cpu_underuse_encode_rsd_threshold ==
+            o.cpu_underuse_encode_rsd_threshold &&
+        cpu_overuse_encode_rsd_threshold ==
+            o.cpu_overuse_encode_rsd_threshold &&
+        cpu_overuse_encode_usage == o.cpu_overuse_encode_usage &&
         conference_mode == o.conference_mode &&
         process_adaptation_threshhold == o.process_adaptation_threshhold &&
         system_low_adaptation_threshhold ==
@@ -337,8 +367,14 @@ struct VideoOptions {
         system_high_adaptation_threshhold ==
             o.system_high_adaptation_threshhold &&
         buffered_mode_latency == o.buffered_mode_latency &&
-        lower_min_bitrate == o.lower_min_bitrate &&
-        dscp == o.dscp;
+        dscp == o.dscp &&
+        suspend_below_min_bitrate == o.suspend_below_min_bitrate &&
+        unsignalled_recv_stream_limit == o.unsignalled_recv_stream_limit &&
+        use_simulcast_adapter == o.use_simulcast_adapter &&
+        screencast_min_bitrate == o.screencast_min_bitrate &&
+        use_improved_wifi_bandwidth_estimator ==
+            o.use_improved_wifi_bandwidth_estimator &&
+        use_payload_padding == o.use_payload_padding;
   }
 
   std::string ToString() const {
@@ -350,23 +386,37 @@ struct VideoOptions {
     ost << ToStringIfSet("adapt view switch", adapt_view_switch);
     ost << ToStringIfSet("video adapt third", video_adapt_third);
     ost << ToStringIfSet("noise reduction", video_noise_reduction);
-    ost << ToStringIfSet("3 layers", video_three_layers);
     ost << ToStringIfSet("1 layer screencast", video_one_layer_screencast);
     ost << ToStringIfSet("high bitrate", video_high_bitrate);
-    ost << ToStringIfSet("watermark", video_watermark);
+    ost << ToStringIfSet("start bitrate", video_start_bitrate);
     ost << ToStringIfSet("video temporal layer screencast",
                          video_temporal_layer_screencast);
-    ost << ToStringIfSet("video temporal layer realtime",
-                         video_temporal_layer_realtime);
     ost << ToStringIfSet("leaky bucket", video_leaky_bucket);
+    ost << ToStringIfSet("highest video bitrate", video_highest_bitrate);
     ost << ToStringIfSet("cpu overuse detection", cpu_overuse_detection);
+    ost << ToStringIfSet("cpu underuse threshold", cpu_underuse_threshold);
+    ost << ToStringIfSet("cpu overuse threshold", cpu_overuse_threshold);
+    ost << ToStringIfSet("cpu underuse encode rsd threshold",
+                         cpu_underuse_encode_rsd_threshold);
+    ost << ToStringIfSet("cpu overuse encode rsd threshold",
+                         cpu_overuse_encode_rsd_threshold);
+    ost << ToStringIfSet("cpu overuse encode usage",
+                         cpu_overuse_encode_usage);
     ost << ToStringIfSet("conference mode", conference_mode);
     ost << ToStringIfSet("process", process_adaptation_threshhold);
     ost << ToStringIfSet("low", system_low_adaptation_threshhold);
     ost << ToStringIfSet("high", system_high_adaptation_threshhold);
     ost << ToStringIfSet("buffered mode latency", buffered_mode_latency);
-    ost << ToStringIfSet("lower min bitrate", lower_min_bitrate);
     ost << ToStringIfSet("dscp", dscp);
+    ost << ToStringIfSet("suspend below min bitrate",
+                         suspend_below_min_bitrate);
+    ost << ToStringIfSet("num channels for early receive",
+                         unsignalled_recv_stream_limit);
+    ost << ToStringIfSet("use simulcast adapter", use_simulcast_adapter);
+    ost << ToStringIfSet("screencast min bitrate", screencast_min_bitrate);
+    ost << ToStringIfSet("improved wifi bwe",
+                         use_improved_wifi_bandwidth_estimator);
+    ost << ToStringIfSet("payload padding", use_payload_padding);
     ost << "}";
     return ost.str();
   }
@@ -383,24 +433,40 @@ struct VideoOptions {
   Settable<bool> video_adapt_third;
   // Enable denoising?
   Settable<bool> video_noise_reduction;
-  // Experimental: Enable multi layer?
-  Settable<bool> video_three_layers;
   // Experimental: Enable one layer screencast?
   Settable<bool> video_one_layer_screencast;
   // Experimental: Enable WebRtc higher bitrate?
   Settable<bool> video_high_bitrate;
-  // Experimental: Add watermark to the rendered video image.
-  Settable<bool> video_watermark;
+  // Experimental: Enable WebRtc higher start bitrate?
+  Settable<int> video_start_bitrate;
   // Experimental: Enable WebRTC layered screencast.
   Settable<bool> video_temporal_layer_screencast;
-  // Experimental: Enable WebRTC temporal layer strategy for realtime video.
-  Settable<bool> video_temporal_layer_realtime;
   // Enable WebRTC leaky bucket when sending media packets.
   Settable<bool> video_leaky_bucket;
+  // Set highest bitrate mode for video.
+  Settable<HighestBitrate> video_highest_bitrate;
   // Enable WebRTC Cpu Overuse Detection, which is a new version of the CPU
   // adaptation algorithm. So this option will override the
   // |adapt_input_to_cpu_usage|.
   Settable<bool> cpu_overuse_detection;
+  // Low threshold (t1) for cpu overuse adaptation.  (Adapt up)
+  // Metric: encode usage (m1). m1 < t1 => underuse.
+  Settable<int> cpu_underuse_threshold;
+  // High threshold (t1) for cpu overuse adaptation.  (Adapt down)
+  // Metric: encode usage (m1). m1 > t1 => overuse.
+  Settable<int> cpu_overuse_threshold;
+  // Low threshold (t2) for cpu overuse adaptation. (Adapt up)
+  // Metric: relative standard deviation of encode time (m2).
+  // Optional threshold. If set, (m1 < t1 && m2 < t2) => underuse.
+  // Note: t2 will have no effect if t1 is not set.
+  Settable<int> cpu_underuse_encode_rsd_threshold;
+  // High threshold (t2) for cpu overuse adaptation. (Adapt down)
+  // Metric: relative standard deviation of encode time (m2).
+  // Optional threshold. If set, (m1 > t1 || m2 > t2) => overuse.
+  // Note: t2 will have no effect if t1 is not set.
+  Settable<int> cpu_overuse_encode_rsd_threshold;
+  // Use encode usage for cpu detection.
+  Settable<bool> cpu_overuse_encode_usage;
   // Use conference mode?
   Settable<bool> conference_mode;
   // Threshhold for process cpu adaptation.  (Process limit)
@@ -411,10 +477,21 @@ struct VideoOptions {
   SettablePercent system_high_adaptation_threshhold;
   // Specify buffered mode latency in milliseconds.
   Settable<int> buffered_mode_latency;
-  // Make minimum configured send bitrate even lower than usual, at 30kbit.
-  Settable<bool> lower_min_bitrate;
   // Set DSCP value for packet sent from video channel.
   Settable<bool> dscp;
+  // Enable WebRTC suspension of video. No video frames will be sent when the
+  // bitrate is below the configured minimum bitrate.
+  Settable<bool> suspend_below_min_bitrate;
+  // Limit on the number of early receive channels that can be created.
+  Settable<int> unsignalled_recv_stream_limit;
+  // Enable use of simulcast adapter.
+  Settable<bool> use_simulcast_adapter;
+  // Force screencast to use a minimum bitrate
+  Settable<int> screencast_min_bitrate;
+  // Enable improved bandwidth estiamtor on wifi.
+  Settable<bool> use_improved_wifi_bandwidth_estimator;
+  // Enable payload padding.
+  Settable<bool> use_payload_padding;
 };
 
 // A class for playing out soundclips.
@@ -483,12 +560,12 @@ class MediaChannel : public sigslot::has_slots<> {
    public:
     enum SocketType { ST_RTP, ST_RTCP };
     virtual bool SendPacket(
-        talk_base::Buffer* packet,
-        talk_base::DiffServCodePoint dscp = talk_base::DSCP_NO_CHANGE) = 0;
+        rtc::Buffer* packet,
+        rtc::DiffServCodePoint dscp = rtc::DSCP_NO_CHANGE) = 0;
     virtual bool SendRtcp(
-        talk_base::Buffer* packet,
-        talk_base::DiffServCodePoint dscp = talk_base::DSCP_NO_CHANGE) = 0;
-    virtual int SetOption(SocketType type, talk_base::Socket::Option opt,
+        rtc::Buffer* packet,
+        rtc::DiffServCodePoint dscp = rtc::DSCP_NO_CHANGE) = 0;
+    virtual int SetOption(SocketType type, rtc::Socket::Option opt,
                           int option) = 0;
     virtual ~NetworkInterface() {}
   };
@@ -498,14 +575,16 @@ class MediaChannel : public sigslot::has_slots<> {
 
   // Sets the abstract interface class for sending RTP/RTCP data.
   virtual void SetInterface(NetworkInterface *iface) {
-    talk_base::CritScope cs(&network_interface_crit_);
+    rtc::CritScope cs(&network_interface_crit_);
     network_interface_ = iface;
   }
 
   // Called when a RTP packet is received.
-  virtual void OnPacketReceived(talk_base::Buffer* packet) = 0;
+  virtual void OnPacketReceived(rtc::Buffer* packet,
+                                const rtc::PacketTime& packet_time) = 0;
   // Called when a RTCP packet is received.
-  virtual void OnRtcpReceived(talk_base::Buffer* packet) = 0;
+  virtual void OnRtcpReceived(rtc::Buffer* packet,
+                              const rtc::PacketTime& packet_time) = 0;
   // Called when the socket's ability to send has changed.
   virtual void OnReadyToSend(bool ready) = 0;
   // Creates a new outgoing media stream with SSRCs and CNAME as described
@@ -531,22 +610,28 @@ class MediaChannel : public sigslot::has_slots<> {
       const std::vector<RtpHeaderExtension>& extensions) = 0;
   virtual bool SetSendRtpHeaderExtensions(
       const std::vector<RtpHeaderExtension>& extensions) = 0;
-  // Sets the rate control to use when sending data.
-  virtual bool SetSendBandwidth(bool autobw, int bps) = 0;
+  // Returns the absoulte sendtime extension id value from media channel.
+  virtual int GetRtpSendTimeExtnId() const {
+    return -1;
+  }
+  // Sets the initial bandwidth to use when sending starts.
+  virtual bool SetStartSendBandwidth(int bps) = 0;
+  // Sets the maximum allowed bandwidth to use when sending data.
+  virtual bool SetMaxSendBandwidth(int bps) = 0;
 
   // Base method to send packet using NetworkInterface.
-  bool SendPacket(talk_base::Buffer* packet) {
+  bool SendPacket(rtc::Buffer* packet) {
     return DoSendPacket(packet, false);
   }
 
-  bool SendRtcp(talk_base::Buffer* packet) {
+  bool SendRtcp(rtc::Buffer* packet) {
     return DoSendPacket(packet, true);
   }
 
   int SetOption(NetworkInterface::SocketType type,
-                talk_base::Socket::Option opt,
+                rtc::Socket::Option opt,
                 int option) {
-    talk_base::CritScope cs(&network_interface_crit_);
+    rtc::CritScope cs(&network_interface_crit_);
     if (!network_interface_)
       return -1;
 
@@ -555,22 +640,22 @@ class MediaChannel : public sigslot::has_slots<> {
 
  protected:
   // This method sets DSCP |value| on both RTP and RTCP channels.
-  int SetDscp(talk_base::DiffServCodePoint value) {
+  int SetDscp(rtc::DiffServCodePoint value) {
     int ret;
     ret = SetOption(NetworkInterface::ST_RTP,
-                    talk_base::Socket::OPT_DSCP,
+                    rtc::Socket::OPT_DSCP,
                     value);
     if (ret == 0) {
       ret = SetOption(NetworkInterface::ST_RTCP,
-                      talk_base::Socket::OPT_DSCP,
+                      rtc::Socket::OPT_DSCP,
                       value);
     }
     return ret;
   }
 
  private:
-  bool DoSendPacket(talk_base::Buffer* packet, bool rtcp) {
-    talk_base::CritScope cs(&network_interface_crit_);
+  bool DoSendPacket(rtc::Buffer* packet, bool rtcp) {
+    rtc::CritScope cs(&network_interface_crit_);
     if (!network_interface_)
       return false;
 
@@ -581,7 +666,7 @@ class MediaChannel : public sigslot::has_slots<> {
   // |network_interface_| can be accessed from the worker_thread and
   // from any MediaEngine threads. This critical section is to protect accessing
   // of network_interface_ object.
-  talk_base::CriticalSection network_interface_crit_;
+  rtc::CriticalSection network_interface_crit_;
   NetworkInterface* network_interface_;
 };
 
@@ -624,6 +709,35 @@ struct MediaSenderInfo {
         fraction_lost(0.0),
         rtt_ms(0) {
   }
+  void add_ssrc(const SsrcSenderInfo& stat) {
+    local_stats.push_back(stat);
+  }
+  // Temporary utility function for call sites that only provide SSRC.
+  // As more info is added into SsrcSenderInfo, this function should go away.
+  void add_ssrc(uint32 ssrc) {
+    SsrcSenderInfo stat;
+    stat.ssrc = ssrc;
+    add_ssrc(stat);
+  }
+  // Utility accessor for clients that are only interested in ssrc numbers.
+  std::vector<uint32> ssrcs() const {
+    std::vector<uint32> retval;
+    for (std::vector<SsrcSenderInfo>::const_iterator it = local_stats.begin();
+         it != local_stats.end(); ++it) {
+      retval.push_back(it->ssrc);
+    }
+    return retval;
+  }
+  // Utility accessor for clients that make the assumption only one ssrc
+  // exists per media.
+  // This will eventually go away.
+  uint32 ssrc() const {
+    if (local_stats.size() > 0) {
+      return local_stats[0].ssrc;
+    } else {
+      return 0;
+    }
+  }
   int64 bytes_sent;
   int packets_sent;
   int packets_lost;
@@ -634,6 +748,20 @@ struct MediaSenderInfo {
   std::vector<SsrcReceiverInfo> remote_stats;
 };
 
+template<class T>
+struct VariableInfo {
+  VariableInfo()
+      : min_val(),
+        mean(0.0),
+        max_val(),
+        variance(0.0) {
+  }
+  T min_val;
+  double mean;
+  T max_val;
+  double variance;
+};
+
 struct MediaReceiverInfo {
   MediaReceiverInfo()
       : bytes_rcvd(0),
@@ -641,18 +769,47 @@ struct MediaReceiverInfo {
         packets_lost(0),
         fraction_lost(0.0) {
   }
+  void add_ssrc(const SsrcReceiverInfo& stat) {
+    local_stats.push_back(stat);
+  }
+  // Temporary utility function for call sites that only provide SSRC.
+  // As more info is added into SsrcSenderInfo, this function should go away.
+  void add_ssrc(uint32 ssrc) {
+    SsrcReceiverInfo stat;
+    stat.ssrc = ssrc;
+    add_ssrc(stat);
+  }
+  std::vector<uint32> ssrcs() const {
+    std::vector<uint32> retval;
+    for (std::vector<SsrcReceiverInfo>::const_iterator it = local_stats.begin();
+         it != local_stats.end(); ++it) {
+      retval.push_back(it->ssrc);
+    }
+    return retval;
+  }
+  // Utility accessor for clients that make the assumption only one ssrc
+  // exists per media.
+  // This will eventually go away.
+  uint32 ssrc() const {
+    if (local_stats.size() > 0) {
+      return local_stats[0].ssrc;
+    } else {
+      return 0;
+    }
+  }
+
   int64 bytes_rcvd;
   int packets_rcvd;
   int packets_lost;
   float fraction_lost;
+  std::string codec_name;
   std::vector<SsrcReceiverInfo> local_stats;
   std::vector<SsrcSenderInfo> remote_stats;
 };
 
 struct VoiceSenderInfo : public MediaSenderInfo {
   VoiceSenderInfo()
-      : ssrc(0),
-        ext_seqnum(0),
+      : ext_seqnum(0),
         jitter_ms(0),
         audio_level(0),
         aec_quality_min(0.0),
@@ -663,7 +820,6 @@ struct VoiceSenderInfo : public MediaSenderInfo {
         typing_noise_detected(false) {
   }
 
-  uint32 ssrc;
   int ext_seqnum;
   int jitter_ms;
   int audio_level;
@@ -677,17 +833,22 @@ struct VoiceSenderInfo : public MediaSenderInfo {
 
 struct VoiceReceiverInfo : public MediaReceiverInfo {
   VoiceReceiverInfo()
-      : ssrc(0),
-        ext_seqnum(0),
+      : ext_seqnum(0),
         jitter_ms(0),
         jitter_buffer_ms(0),
         jitter_buffer_preferred_ms(0),
         delay_estimate_ms(0),
         audio_level(0),
-        expand_rate(0) {
+        expand_rate(0),
+        decoding_calls_to_silence_generator(0),
+        decoding_calls_to_neteq(0),
+        decoding_normal(0),
+        decoding_plc(0),
+        decoding_cng(0),
+        decoding_plc_cng(0),
+        capture_start_ntp_time_ms(-1) {
   }
 
-  uint32 ssrc;
   int ext_seqnum;
   int jitter_ms;
   int jitter_buffer_ms;
@@ -696,40 +857,69 @@ struct VoiceReceiverInfo : public MediaReceiverInfo {
   int audio_level;
   // fraction of synthesized speech inserted through pre-emptive expansion
   float expand_rate;
+  int decoding_calls_to_silence_generator;
+  int decoding_calls_to_neteq;
+  int decoding_normal;
+  int decoding_plc;
+  int decoding_cng;
+  int decoding_plc_cng;
+  // Estimated capture start time in NTP time in ms.
+  int64 capture_start_ntp_time_ms;
 };
 
 struct VideoSenderInfo : public MediaSenderInfo {
   VideoSenderInfo()
       : packets_cached(0),
         firs_rcvd(0),
+        plis_rcvd(0),
         nacks_rcvd(0),
-        frame_width(0),
-        frame_height(0),
+        input_frame_width(0),
+        input_frame_height(0),
+        send_frame_width(0),
+        send_frame_height(0),
         framerate_input(0),
         framerate_sent(0),
         nominal_bitrate(0),
         preferred_bitrate(0),
-        adapt_reason(0) {
+        adapt_reason(0),
+        adapt_changes(0),
+        capture_jitter_ms(0),
+        avg_encode_ms(0),
+        encode_usage_percent(0),
+        encode_rsd(0),
+        capture_queue_delay_ms_per_s(0) {
   }
 
-  std::vector<uint32> ssrcs;
   std::vector<SsrcGroup> ssrc_groups;
   int packets_cached;
   int firs_rcvd;
+  int plis_rcvd;
   int nacks_rcvd;
-  int frame_width;
-  int frame_height;
+  int input_frame_width;
+  int input_frame_height;
+  int send_frame_width;
+  int send_frame_height;
   int framerate_input;
   int framerate_sent;
   int nominal_bitrate;
   int preferred_bitrate;
   int adapt_reason;
+  int adapt_changes;
+  int capture_jitter_ms;
+  int avg_encode_ms;
+  int encode_usage_percent;
+  int encode_rsd;
+  int capture_queue_delay_ms_per_s;
+  VariableInfo<int> adapt_frame_drops;
+  VariableInfo<int> effects_frame_drops;
+  VariableInfo<double> capturer_frame_time;
 };
 
 struct VideoReceiverInfo : public MediaReceiverInfo {
   VideoReceiverInfo()
       : packets_concealed(0),
         firs_sent(0),
+        plis_sent(0),
         nacks_sent(0),
         frame_width(0),
         frame_height(0),
@@ -744,13 +934,14 @@ struct VideoReceiverInfo : public MediaReceiverInfo {
         min_playout_delay_ms(0),
         render_delay_ms(0),
         target_delay_ms(0),
-        current_delay_ms(0) {
+        current_delay_ms(0),
+        capture_start_ntp_time_ms(-1) {
   }
 
-  std::vector<uint32> ssrcs;
   std::vector<SsrcGroup> ssrc_groups;
   int packets_concealed;
   int firs_sent;
+  int plis_sent;
   int nacks_sent;
   int frame_width;
   int frame_height;
@@ -781,6 +972,9 @@ struct VideoReceiverInfo : public MediaReceiverInfo {
   int target_delay_ms;
   // Current overall delay, possibly ramping towards target_delay_ms.
   int current_delay_ms;
+
+  // Estimated capture start time in NTP time in ms.
+  int64 capture_start_ntp_time_ms;
 };
 
 struct DataSenderInfo : public MediaSenderInfo {
@@ -807,7 +1001,8 @@ struct BandwidthEstimationInfo {
         actual_enc_bitrate(0),
         retransmit_bitrate(0),
         transmit_bitrate(0),
-        bucket_delay(0) {
+        bucket_delay(0),
+        total_received_propagation_delta_ms(0) {
   }
 
   int available_send_bandwidth;
@@ -817,6 +1012,11 @@ struct BandwidthEstimationInfo {
   int retransmit_bitrate;
   int transmit_bitrate;
   int bucket_delay;
+  // The following stats are only valid when
+  // StatsOptions::include_received_propagation_stats is true.
+  int total_received_propagation_delta_ms;
+  std::vector<int> recent_received_propagation_delta_ms;
+  std::vector<int64> recent_received_packet_group_arrival_time_ms;
 };
 
 struct VoiceMediaInfo {
@@ -848,6 +1048,12 @@ struct DataMediaInfo {
   std::vector<DataReceiverInfo> receivers;
 };
 
+struct StatsOptions {
+  StatsOptions() : include_received_propagation_stats(false) {}
+
+  bool include_received_propagation_stats;
+};
+
 class VoiceMediaChannel : public MediaChannel {
  public:
   enum Error {
@@ -966,7 +1172,12 @@ class VideoMediaChannel : public MediaChannel {
   // |capturer|. If |ssrc| is non zero create a new stream with |ssrc| as SSRC.
   virtual bool SetCapturer(uint32 ssrc, VideoCapturer* capturer) = 0;
   // Gets quality stats for the channel.
-  virtual bool GetStats(VideoMediaInfo* info) = 0;
+  virtual bool GetStats(const StatsOptions& options, VideoMediaInfo* info) = 0;
+  // This is needed for MediaMonitor to use the same template for voice, video
+  // and data MediaChannels.
+  bool GetStats(VideoMediaInfo* info) {
+    return GetStats(StatsOptions(), info);
+  }
 
   // Send an intra frame to the receivers.
   virtual bool SendIntraFrame() = 0;
@@ -1065,29 +1276,19 @@ class DataMediaChannel : public MediaChannel {
 
   virtual ~DataMediaChannel() {}
 
-  virtual bool SetSendBandwidth(bool autobw, int bps) = 0;
   virtual bool SetSendCodecs(const std::vector<DataCodec>& codecs) = 0;
   virtual bool SetRecvCodecs(const std::vector<DataCodec>& codecs) = 0;
-  virtual bool SetRecvRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) = 0;
-  virtual bool SetSendRtpHeaderExtensions(
-      const std::vector<RtpHeaderExtension>& extensions) = 0;
-  virtual bool AddSendStream(const StreamParams& sp) = 0;
-  virtual bool RemoveSendStream(uint32 ssrc) = 0;
-  virtual bool AddRecvStream(const StreamParams& sp) = 0;
-  virtual bool RemoveRecvStream(uint32 ssrc) = 0;
+
   virtual bool MuteStream(uint32 ssrc, bool on) { return false; }
   // TODO(pthatcher): Implement this.
   virtual bool GetStats(DataMediaInfo* info) { return true; }
 
   virtual bool SetSend(bool send) = 0;
   virtual bool SetReceive(bool receive) = 0;
-  virtual void OnPacketReceived(talk_base::Buffer* packet) = 0;
-  virtual void OnRtcpReceived(talk_base::Buffer* packet) = 0;
 
   virtual bool SendData(
       const SendDataParams& params,
-      const talk_base::Buffer& payload,
+      const rtc::Buffer& payload,
       SendDataResult* result = NULL) = 0;
   // Signals when data is received (params, data, len)
   sigslot::signal3<const ReceiveDataParams&,
@@ -1099,11 +1300,8 @@ class DataMediaChannel : public MediaChannel {
   // Signal when the media channel is ready to send the stream. Arguments are:
   //     writable(bool)
   sigslot::signal1<bool> SignalReadyToSend;
-  // Signal for notifying when a new stream is added from the remote side. Used
-  // for the in-band negotioation through the OPEN message for SCTP data
-  // channel.
-  sigslot::signal2<const std::string&, const webrtc::DataChannelInit&>
-      SignalNewStreamReceived;
+  // Signal for notifying that the remote side has closed the DataChannel.
+  sigslot::signal1<uint32> SignalStreamClosedRemotely;
 };
 
 }  // namespace cricket