Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / video / video_receive_stream.cc
index 71fc152..337eda4 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
 #include "webrtc/system_wrappers/interface/clock.h"
+#include "webrtc/video/receive_statistics_proxy.h"
 #include "webrtc/video_engine/include/vie_base.h"
 #include "webrtc/video_engine/include/vie_capture.h"
 #include "webrtc/video_engine/include/vie_codec.h"
@@ -38,6 +39,7 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
     : transport_adapter_(transport),
       encoded_frame_proxy_(config.pre_decode_callback),
       config_(config),
+      clock_(Clock::GetRealTimeClock()),
       channel_(-1) {
   video_engine_base_ = ViEBase::GetInterface(video_engine);
   video_engine_base_->CreateReceiveChannel(channel_, base_channel);
@@ -59,10 +61,21 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
   }
 
   assert(config_.rtp.remote_ssrc != 0);
+  // TODO(pbos): What's an appropriate local_ssrc for receive-only streams?
   assert(config_.rtp.local_ssrc != 0);
   assert(config_.rtp.remote_ssrc != config_.rtp.local_ssrc);
 
   rtp_rtcp_->SetLocalSSRC(channel_, config_.rtp.local_ssrc);
+  // TODO(pbos): Support multiple RTX, per video payload.
+  Config::Rtp::RtxMap::const_iterator it = config_.rtp.rtx.begin();
+  if (it != config_.rtp.rtx.end()) {
+    assert(it->second.ssrc != 0);
+    assert(it->second.payload_type != 0);
+
+    rtp_rtcp_->SetRemoteSSRCType(channel_, kViEStreamTypeRtx, it->second.ssrc);
+    rtp_rtcp_->SetRtxReceivePayloadType(channel_, it->second.payload_type);
+  }
+
   rtp_rtcp_->SetRembStatus(channel_, false, config_.rtp.remb);
 
   for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) {
@@ -94,6 +107,20 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
     }
   }
 
+  stats_proxy_.reset(new ReceiveStatisticsProxy(
+      config_.rtp.local_ssrc, clock_, rtp_rtcp_, codec_, channel_));
+
+  if (rtp_rtcp_->RegisterReceiveChannelRtcpStatisticsCallback(
+          channel_, stats_proxy_.get()) != 0)
+    abort();
+
+  if (rtp_rtcp_->RegisterReceiveChannelRtpStatisticsCallback(
+          channel_, stats_proxy_.get()) != 0)
+    abort();
+
+  if (codec_->RegisterDecoderObserver(channel_, *stats_proxy_) != 0)
+    abort();
+
   external_codec_ = ViEExternalCodec::GetInterface(video_engine);
   for (size_t i = 0; i < config_.external_decoders.size(); ++i) {
     ExternalVideoDecoder* decoder = &config_.external_decoders[i];
@@ -102,8 +129,7 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
             decoder->payload_type,
             decoder->decoder,
             decoder->renderer,
-            decoder->expected_delay_ms) !=
-        0) {
+            decoder->expected_delay_ms) != 0) {
       // TODO(pbos): Abort gracefully? Can this be a runtime error?
       abort();
     }
@@ -124,14 +150,11 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
     image_process_->RegisterPreDecodeImageCallback(channel_,
                                                    &encoded_frame_proxy_);
   }
-  image_process_->RegisterPreRenderCallback(channel_,
-                                            config_.pre_render_callback);
+  image_process_->RegisterPreRenderCallback(channel_, this);
 
   if (config.rtp.rtcp_xr.receiver_reference_time_report) {
     rtp_rtcp_->SetRtcpXrRrtrStatus(channel_, true);
   }
-
-  clock_ = Clock::GetRealTimeClock();
 }
 
 VideoReceiveStream::~VideoReceiveStream() {
@@ -151,6 +174,11 @@ VideoReceiveStream::~VideoReceiveStream() {
   image_process_->Release();
   video_engine_base_->Release();
   external_codec_->Release();
+  codec_->DeregisterDecoderObserver(channel_);
+  rtp_rtcp_->DeregisterReceiveChannelRtpStatisticsCallback(channel_,
+                                                           stats_proxy_.get());
+  rtp_rtcp_->DeregisterReceiveChannelRtcpStatisticsCallback(channel_,
+                                                            stats_proxy_.get());
   codec_->Release();
   network_->Release();
   render_->Release();
@@ -158,6 +186,7 @@ VideoReceiveStream::~VideoReceiveStream() {
 }
 
 void VideoReceiveStream::StartReceiving() {
+  transport_adapter_.Enable();
   if (render_->StartRender(channel_) != 0)
     abort();
   if (video_engine_base_->StartReceive(channel_) != 0)
@@ -169,6 +198,11 @@ void VideoReceiveStream::StopReceiving() {
     abort();
   if (video_engine_base_->StopReceive(channel_) != 0)
     abort();
+  transport_adapter_.Disable();
+}
+
+VideoReceiveStream::Stats VideoReceiveStream::GetStats() const {
+  return stats_proxy_->GetStats();
 }
 
 void VideoReceiveStream::GetCurrentReceiveCodec(VideoCodec* receive_codec) {
@@ -182,17 +216,25 @@ bool VideoReceiveStream::DeliverRtcp(const uint8_t* packet, size_t length) {
 
 bool VideoReceiveStream::DeliverRtp(const uint8_t* packet, size_t length) {
   return network_->ReceivedRTPPacket(
-             channel_, packet, static_cast<int>(length),
-             PacketTime()) == 0;
+             channel_, packet, static_cast<int>(length), PacketTime()) == 0;
+}
+
+void VideoReceiveStream::FrameCallback(I420VideoFrame* video_frame) {
+  stats_proxy_->OnDecodedFrame();
+
+  if (config_.pre_render_callback)
+    config_.pre_render_callback->FrameCallback(video_frame);
 }
 
 int32_t VideoReceiveStream::RenderFrame(const uint32_t stream_id,
                                         I420VideoFrame& video_frame) {
-  if (config_.renderer == NULL)
-    return 0;
+  if (config_.renderer != NULL)
+    config_.renderer->RenderFrame(
+        video_frame,
+        video_frame.render_time_ms() - clock_->TimeInMilliseconds());
+
+  stats_proxy_->OnRenderedFrame();
 
-  config_.renderer->RenderFrame(
-      video_frame, video_frame.render_time_ms() - clock_->TimeInMilliseconds());
   return 0;
 }
 }  // namespace internal