Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / media / webrtc / webrtcvideoengine.cc
index ca0ed41..3e6f928 100644 (file)
@@ -60,6 +60,7 @@
 #include "talk/media/webrtc/webrtcvie.h"
 #include "talk/media/webrtc/webrtcvoe.h"
 #include "talk/media/webrtc/webrtcvoiceengine.h"
+#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
 
 #if !defined(LIBPEERCONNECTION_LIB)
 #ifndef HAVE_WEBRTC_VIDEO
@@ -583,13 +584,12 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> {
         external_capture_(external_capture),
         capturer_updated_(false),
         interval_(0),
-        video_adapter_(new CoordinatedVideoAdapter),
         cpu_monitor_(cpu_monitor) {
-    overuse_observer_.reset(new WebRtcOveruseObserver(video_adapter_.get()));
-    SignalCpuAdaptationUnable.repeat(video_adapter_->SignalCpuAdaptationUnable);
+    overuse_observer_.reset(new WebRtcOveruseObserver(&video_adapter_));
+    SignalCpuAdaptationUnable.repeat(video_adapter_.SignalCpuAdaptationUnable);
     if (cpu_monitor) {
       cpu_monitor->SignalUpdate.connect(
-          video_adapter_.get(), &CoordinatedVideoAdapter::OnCpuLoadUpdated);
+          &video_adapter_, &CoordinatedVideoAdapter::OnCpuLoadUpdated);
     }
   }
 
@@ -599,7 +599,7 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> {
   bool sending() const { return sending_; }
   void set_muted(bool on) {
     // TODO(asapersson): add support.
-    // video_adapter_->SetBlackOutput(on);
+    // video_adapter_.SetBlackOutput(on);
     muted_ = on;
   }
   bool muted() {return muted_; }
@@ -614,7 +614,7 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> {
     if (video_format_ != cricket::VideoFormat()) {
       interval_ = video_format_.interval;
     }
-    video_adapter_->OnOutputFormatRequest(video_format_);
+    video_adapter_.OnOutputFormatRequest(video_format_);
   }
   void set_interval(int64 interval) {
     if (video_format() == cricket::VideoFormat()) {
@@ -627,17 +627,13 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> {
     VideoFormat format(codec.width, codec.height,
                        VideoFormat::FpsToInterval(codec.maxFramerate),
                        FOURCC_I420);
-    if (video_adapter_->output_format().IsSize0x0()) {
-      video_adapter_->SetOutputFormat(format);
+    if (video_adapter_.output_format().IsSize0x0()) {
+      video_adapter_.SetOutputFormat(format);
     }
   }
 
-  bool AdaptFrame(const VideoFrame* in_frame, const VideoFrame** out_frame) {
-    *out_frame = NULL;
-    return video_adapter_->AdaptFrame(in_frame, out_frame);
-  }
   int CurrentAdaptReason() const {
-    return video_adapter_->adapt_reason();
+    return video_adapter_.adapt_reason();
   }
   webrtc::CpuOveruseObserver* overuse_observer() {
     return overuse_observer_.get();
@@ -663,6 +659,12 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> {
       return;
     }
     capturer_updated_ = true;
+
+    // Disconnect from the previous video capturer.
+    if (video_capturer_) {
+      video_capturer_->SignalAdaptFrame.disconnect(this);
+    }
+
     video_capturer_ = video_capturer;
     if (video_capturer && !video_capturer->IsScreencast()) {
       const VideoFormat* capture_format = video_capturer->GetCaptureFormat();
@@ -674,40 +676,51 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> {
         // be zero, and all frames may be dropped.
         // Consider fixing this by having video_adapter keep a pointer to the
         // video capturer.
-        video_adapter_->SetInputFormat(*capture_format);
+        video_adapter_.SetInputFormat(*capture_format);
       }
+      // TODO(thorcarpenter): When the adapter supports "only frame dropping"
+      // mode, also hook it up to screencast capturers.
+      video_capturer->SignalAdaptFrame.connect(
+          this, &WebRtcVideoChannelSendInfo::AdaptFrame);
     }
   }
 
+  CoordinatedVideoAdapter* video_adapter() { return &video_adapter_; }
+
+  void AdaptFrame(VideoCapturer* capturer, const VideoFrame* input,
+                  VideoFrame** adapted) {
+    video_adapter_.AdaptFrame(input, adapted);
+  }
+
   void ApplyCpuOptions(const VideoOptions& options) {
     bool cpu_adapt, cpu_smoothing, adapt_third;
     float low, med, high;
     if (options.adapt_input_to_cpu_usage.Get(&cpu_adapt)) {
-      video_adapter_->set_cpu_adaptation(cpu_adapt);
+      video_adapter_.set_cpu_adaptation(cpu_adapt);
     }
     if (options.adapt_cpu_with_smoothing.Get(&cpu_smoothing)) {
-      video_adapter_->set_cpu_smoothing(cpu_smoothing);
+      video_adapter_.set_cpu_smoothing(cpu_smoothing);
     }
     if (options.process_adaptation_threshhold.Get(&med)) {
-      video_adapter_->set_process_threshold(med);
+      video_adapter_.set_process_threshold(med);
     }
     if (options.system_low_adaptation_threshhold.Get(&low)) {
-      video_adapter_->set_low_system_threshold(low);
+      video_adapter_.set_low_system_threshold(low);
     }
     if (options.system_high_adaptation_threshhold.Get(&high)) {
-      video_adapter_->set_high_system_threshold(high);
+      video_adapter_.set_high_system_threshold(high);
     }
     if (options.video_adapt_third.Get(&adapt_third)) {
-      video_adapter_->set_scale_third(adapt_third);
+      video_adapter_.set_scale_third(adapt_third);
     }
   }
 
   void SetCpuOveruseDetection(bool enable) {
     if (cpu_monitor_ && enable) {
-      cpu_monitor_->SignalUpdate.disconnect(video_adapter_.get());
+      cpu_monitor_->SignalUpdate.disconnect(&video_adapter_);
     }
     overuse_observer_->Enable(enable);
-    video_adapter_->set_cpu_adaptation(enable);
+    video_adapter_.set_cpu_adaptation(enable);
   }
 
   void ProcessFrame(const VideoFrame& original_frame, bool mute,
@@ -761,7 +774,7 @@ class WebRtcVideoChannelSendInfo : public sigslot::has_slots<> {
 
   int64 interval_;
 
-  talk_base::scoped_ptr<CoordinatedVideoAdapter> video_adapter_;
+  CoordinatedVideoAdapter video_adapter_;
   talk_base::CpuMonitor* cpu_monitor_;
   talk_base::scoped_ptr<WebRtcOveruseObserver> overuse_observer_;
 };
@@ -2241,7 +2254,8 @@ bool WebRtcVideoMediaChannel::SetRenderer(uint32 ssrc,
   return true;
 }
 
-bool WebRtcVideoMediaChannel::GetStats(VideoMediaInfo* info) {
+bool WebRtcVideoMediaChannel::GetStats(const StatsOptions& options,
+                                       VideoMediaInfo* info) {
   // Get sender statistics and build VideoSenderInfo.
   unsigned int total_bitrate_sent = 0;
   unsigned int video_bitrate_sent = 0;
@@ -2288,8 +2302,18 @@ bool WebRtcVideoMediaChannel::GetStats(VideoMediaInfo* info) {
       sinfo.firs_rcvd = -1;
       sinfo.nacks_rcvd = -1;
       sinfo.rtt_ms = -1;
-      sinfo.frame_width = static_cast<int>(channel_stream_info->width());
-      sinfo.frame_height = static_cast<int>(channel_stream_info->height());
+      sinfo.input_frame_width = static_cast<int>(channel_stream_info->width());
+      sinfo.input_frame_height =
+          static_cast<int>(channel_stream_info->height());
+      webrtc::VideoCodec vie_codec;
+      if (engine()->vie()->codec()->GetSendCodec(channel_id, vie_codec) == 0) {
+        sinfo.send_frame_width = vie_codec.width;
+        sinfo.send_frame_height = vie_codec.height;
+      } else {
+        sinfo.send_frame_width = -1;
+        sinfo.send_frame_height = -1;
+        LOG_RTCERR1(GetSendCodec, channel_id);
+      }
       sinfo.framerate_input = channel_stream_info->framerate();
       sinfo.framerate_sent = send_channel->encoder_observer()->framerate();
       sinfo.nominal_bitrate = send_channel->encoder_observer()->bitrate();
@@ -2431,11 +2455,29 @@ bool WebRtcVideoMediaChannel::GetStats(VideoMediaInfo* info) {
       LOG_RTCERR1(GetEstimatedReceiveBandwidth, channel->channel_id());
     }
   }
-
   // Build BandwidthEstimationInfo.
   // TODO(zhurunz): Add real unittest for this.
   BandwidthEstimationInfo bwe;
 
+  // TODO(jiayl): remove the condition when the necessary changes are available
+  // outside the dev branch.
+#ifdef USE_WEBRTC_DEV_BRANCH
+  if (options.include_received_propagation_stats) {
+    webrtc::ReceiveBandwidthEstimatorStats additional_stats;
+    // Only call for the default channel because the returned stats are
+    // collected for all the channels using the same estimator.
+    if (engine_->vie()->rtp()->GetReceiveBandwidthEstimatorStats(
+        recv_channels_[0]->channel_id(), &additional_stats) == 0) {
+      bwe.total_received_propagation_delta_ms =
+          additional_stats.total_propagation_time_delta_ms;
+      bwe.recent_received_propagation_delta_ms.swap(
+          additional_stats.recent_propagation_time_delta_ms);
+      bwe.recent_received_packet_group_arrival_time_ms.swap(
+          additional_stats.recent_arrival_time_ms);
+    }
+  }
+#endif
+
   // Calculations done above per send/receive stream.
   bwe.actual_enc_bitrate = video_bitrate_sent;
   bwe.transmit_bitrate = total_bitrate_sent;
@@ -2610,9 +2652,27 @@ bool WebRtcVideoMediaChannel::SetSendRtpHeaderExtensions(
       return false;
     }
   }
+
+  if (send_time_extension) {
+    // For video RTP packets, we would like to update AbsoluteSendTimeHeader
+    // Extension closer to the network, @ socket level before sending.
+    // Pushing the extension id to socket layer.
+    MediaChannel::SetOption(NetworkInterface::ST_RTP,
+                            talk_base::Socket::OPT_RTP_SENDTIME_EXTN_ID,
+                            send_time_extension->id);
+  }
   return true;
 }
 
+int WebRtcVideoMediaChannel::GetRtpSendTimeExtnId() const {
+  const RtpHeaderExtension* send_time_extension = FindHeaderExtension(
+      send_extensions_, kRtpAbsoluteSendTimeHeaderExtension);
+  if (send_time_extension) {
+    return send_time_extension->id;
+  }
+  return -1;
+}
+
 bool WebRtcVideoMediaChannel::SetStartSendBandwidth(int bps) {
   LOG(LS_INFO) << "WebRtcVideoMediaChannel::SetStartSendBandwidth";
 
@@ -2854,7 +2914,16 @@ bool WebRtcVideoMediaChannel::GetRenderer(uint32 ssrc,
   return true;
 }
 
-// TODO(zhurunz): Add unittests to test this function.
+bool WebRtcVideoMediaChannel::GetVideoAdapter(
+    uint32 ssrc, CoordinatedVideoAdapter** video_adapter) {
+  SendChannelMap::iterator it = send_channels_.find(ssrc);
+  if (it == send_channels_.end()) {
+    return false;
+  }
+  *video_adapter = it->second->video_adapter();
+  return true;
+}
+
 void WebRtcVideoMediaChannel::SendFrame(VideoCapturer* capturer,
                                         const VideoFrame* frame) {
   // If the |capturer| is registered to any send channel, then send the frame
@@ -3052,6 +3121,13 @@ bool WebRtcVideoMediaChannel::ConfigureChannel(int channel_id,
     }
   }
 
+  // Start receiving for both receive and send channels so that we get incoming
+  // RTP (if receiving) as well as RTCP feedback (if sending).
+  if (engine()->vie()->base()->StartReceive(channel_id) != 0) {
+    LOG_RTCERR1(StartReceive, channel_id);
+    return false;
+  }
+
   return true;
 }
 
@@ -3501,14 +3577,6 @@ bool WebRtcVideoMediaChannel::SetReceiveCodecs(
       }
     }
   }
-
-  // Start receiving packets if at least one receive codec has been set.
-  if (!receive_codecs_.empty()) {
-    if (engine()->vie()->base()->StartReceive(channel_id) != 0) {
-      LOG_RTCERR1(StartReceive, channel_id);
-      return false;
-    }
-  }
   return true;
 }