LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/video - rtp_streams_synchronizer.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 103 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/video/rtp_streams_synchronizer.h"
      12             : 
      13             : #include "webrtc/base/checks.h"
      14             : #include "webrtc/base/logging.h"
      15             : #include "webrtc/base/timeutils.h"
      16             : #include "webrtc/base/trace_event.h"
      17             : #include "webrtc/modules/rtp_rtcp/include/rtp_receiver.h"
      18             : #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
      19             : #include "webrtc/modules/video_coding/video_coding_impl.h"
      20             : #include "webrtc/system_wrappers/include/clock.h"
      21             : #include "webrtc/video/stream_synchronization.h"
      22             : #include "webrtc/video_frame.h"
      23             : #include "webrtc/voice_engine/include/voe_video_sync.h"
      24             : 
      25             : namespace webrtc {
      26             : namespace {
      27           0 : bool UpdateMeasurements(StreamSynchronization::Measurements* stream,
      28             :                         RtpRtcp* rtp_rtcp,
      29             :                         RtpReceiver* receiver) {
      30           0 :   if (!receiver->Timestamp(&stream->latest_timestamp))
      31           0 :     return false;
      32           0 :   if (!receiver->LastReceivedTimeMs(&stream->latest_receive_time_ms))
      33           0 :     return false;
      34             : 
      35           0 :   uint32_t ntp_secs = 0;
      36           0 :   uint32_t ntp_frac = 0;
      37           0 :   uint32_t rtp_timestamp = 0;
      38           0 :   if (rtp_rtcp->RemoteNTP(&ntp_secs, &ntp_frac, nullptr, nullptr,
      39           0 :                           &rtp_timestamp) != 0) {
      40           0 :     return false;
      41             :   }
      42             : 
      43           0 :   bool new_rtcp_sr = false;
      44           0 :   if (!stream->rtp_to_ntp.UpdateMeasurements(ntp_secs, ntp_frac, rtp_timestamp,
      45             :                                              &new_rtcp_sr)) {
      46           0 :     return false;
      47             :   }
      48             : 
      49           0 :   return true;
      50             : }
      51             : }  // namespace
      52             : 
      53           0 : RtpStreamsSynchronizer::RtpStreamsSynchronizer(
      54             :     vcm::VideoReceiver* video_receiver,
      55           0 :     RtpStreamReceiver* rtp_stream_receiver)
      56           0 :     : clock_(Clock::GetRealTimeClock()),
      57             :       video_receiver_(video_receiver),
      58           0 :       video_rtp_receiver_(rtp_stream_receiver->GetRtpReceiver()),
      59           0 :       video_rtp_rtcp_(rtp_stream_receiver->rtp_rtcp()),
      60             :       voe_channel_id_(-1),
      61             :       voe_sync_interface_(nullptr),
      62             :       audio_rtp_receiver_(nullptr),
      63             :       audio_rtp_rtcp_(nullptr),
      64             :       sync_(),
      65           0 :       last_sync_time_(rtc::TimeNanos()) {
      66           0 :   process_thread_checker_.DetachFromThread();
      67           0 : }
      68             : 
      69           0 : void RtpStreamsSynchronizer::ConfigureSync(int voe_channel_id,
      70             :                                            VoEVideoSync* voe_sync_interface) {
      71           0 :   if (voe_channel_id != -1)
      72           0 :     RTC_DCHECK(voe_sync_interface);
      73             : 
      74           0 :   rtc::CritScope lock(&crit_);
      75           0 :   if (voe_channel_id_ == voe_channel_id &&
      76           0 :       voe_sync_interface_ == voe_sync_interface) {
      77             :     // This prevents expensive no-ops.
      78           0 :     return;
      79             :   }
      80           0 :   voe_channel_id_ = voe_channel_id;
      81           0 :   voe_sync_interface_ = voe_sync_interface;
      82             : 
      83           0 :   audio_rtp_rtcp_ = nullptr;
      84           0 :   audio_rtp_receiver_ = nullptr;
      85           0 :   sync_.reset(nullptr);
      86             : 
      87           0 :   if (voe_channel_id_ != -1) {
      88           0 :     voe_sync_interface_->GetRtpRtcp(voe_channel_id_, &audio_rtp_rtcp_,
      89           0 :                                     &audio_rtp_receiver_);
      90           0 :     RTC_DCHECK(audio_rtp_rtcp_);
      91           0 :     RTC_DCHECK(audio_rtp_receiver_);
      92           0 :     sync_.reset(new StreamSynchronization(video_rtp_rtcp_->SSRC(),
      93           0 :                                           voe_channel_id_));
      94             :   }
      95             : }
      96             : 
      97           0 : int64_t RtpStreamsSynchronizer::TimeUntilNextProcess() {
      98           0 :   RTC_DCHECK_RUN_ON(&process_thread_checker_);
      99           0 :   const int64_t kSyncIntervalMs = 1000;
     100             :   return kSyncIntervalMs -
     101           0 :       (rtc::TimeNanos() - last_sync_time_) / rtc::kNumNanosecsPerMillisec;
     102             : }
     103             : 
     104           0 : void RtpStreamsSynchronizer::Process() {
     105           0 :   RTC_DCHECK_RUN_ON(&process_thread_checker_);
     106             : 
     107           0 :   const int current_video_delay_ms = video_receiver_->Delay();
     108           0 :   last_sync_time_ = rtc::TimeNanos();
     109             : 
     110           0 :   rtc::CritScope lock(&crit_);
     111           0 :   if (voe_channel_id_ == -1) {
     112           0 :     return;
     113             :   }
     114           0 :   RTC_DCHECK(voe_sync_interface_);
     115           0 :   RTC_DCHECK(sync_.get());
     116             : 
     117           0 :   int audio_jitter_buffer_delay_ms = 0;
     118           0 :   int playout_buffer_delay_ms = 0;
     119           0 :   int avsync_delay_ms = 0;
     120           0 :   if (voe_sync_interface_->GetDelayEstimate(voe_channel_id_,
     121             :                                             &audio_jitter_buffer_delay_ms,
     122             :                                             &playout_buffer_delay_ms,
     123           0 :                                             &avsync_delay_ms) != 0) {
     124           0 :     return;
     125             :   }
     126           0 :   const int current_audio_delay_ms = audio_jitter_buffer_delay_ms +
     127           0 :       playout_buffer_delay_ms;
     128             : 
     129           0 :   int64_t last_video_receive_ms = video_measurement_.latest_receive_time_ms;
     130           0 :   if (!UpdateMeasurements(&video_measurement_, video_rtp_rtcp_,
     131           0 :                           video_rtp_receiver_)) {
     132           0 :     return;
     133             :   }
     134             : 
     135           0 :   if (!UpdateMeasurements(&audio_measurement_, audio_rtp_rtcp_,
     136             :                           audio_rtp_receiver_)) {
     137           0 :     return;
     138             :   }
     139             : 
     140           0 :   if (last_video_receive_ms == video_measurement_.latest_receive_time_ms) {
     141             :     // No new video packet has been received since last update.
     142           0 :     return;
     143             :   }
     144             : 
     145             :   int relative_delay_ms;
     146             :   // Calculate how much later or earlier the audio stream is compared to video.
     147           0 :   if (!sync_->ComputeRelativeDelay(audio_measurement_, video_measurement_,
     148           0 :                                    &relative_delay_ms)) {
     149           0 :     return;
     150             :   }
     151             : 
     152           0 :   TRACE_COUNTER1("webrtc", "SyncCurrentVideoDelay", current_video_delay_ms);
     153           0 :   TRACE_COUNTER1("webrtc", "SyncCurrentAudioDelay", current_audio_delay_ms);
     154           0 :   TRACE_COUNTER1("webrtc", "SyncRelativeDelay", relative_delay_ms);
     155           0 :   int target_audio_delay_ms = 0;
     156           0 :   int target_video_delay_ms = current_video_delay_ms;
     157             :   // Calculate the necessary extra audio delay and desired total video
     158             :   // delay to get the streams in sync.
     159           0 :   if (!sync_->ComputeDelays(relative_delay_ms,
     160             :                             current_audio_delay_ms,
     161             :                             &target_audio_delay_ms,
     162             :                             &target_video_delay_ms)) {
     163           0 :     return;
     164             :   }
     165             : 
     166           0 :   if (voe_sync_interface_->SetMinimumPlayoutDelay(
     167           0 :       voe_channel_id_, target_audio_delay_ms) == -1) {
     168           0 :     LOG(LS_ERROR) << "Error setting voice delay.";
     169             :   }
     170           0 :   video_receiver_->SetMinimumPlayoutDelay(target_video_delay_ms);
     171             : }
     172             : 
     173           0 : bool RtpStreamsSynchronizer::GetStreamSyncOffsetInMs(
     174             :     const VideoFrame& frame,
     175             :     int64_t* stream_offset_ms,
     176             :     double* estimated_freq_khz) const {
     177           0 :   rtc::CritScope lock(&crit_);
     178           0 :   if (voe_channel_id_ == -1)
     179           0 :     return false;
     180             : 
     181           0 :   uint32_t playout_timestamp = 0;
     182           0 :   if (voe_sync_interface_->GetPlayoutTimestamp(voe_channel_id_,
     183           0 :                                                playout_timestamp) != 0) {
     184           0 :     return false;
     185             :   }
     186             : 
     187             :   int64_t latest_audio_ntp;
     188           0 :   if (!audio_measurement_.rtp_to_ntp.Estimate(playout_timestamp,
     189             :                                               &latest_audio_ntp)) {
     190           0 :     return false;
     191             :   }
     192             : 
     193             :   int64_t latest_video_ntp;
     194           0 :   if (!video_measurement_.rtp_to_ntp.Estimate(frame.timestamp(),
     195             :                                               &latest_video_ntp)) {
     196           0 :     return false;
     197             :   }
     198             : 
     199             :   int64_t time_to_render_ms =
     200           0 :       frame.render_time_ms() - clock_->TimeInMilliseconds();
     201           0 :   if (time_to_render_ms > 0)
     202           0 :     latest_video_ntp += time_to_render_ms;
     203             : 
     204           0 :   *stream_offset_ms = latest_audio_ntp - latest_video_ntp;
     205           0 :   *estimated_freq_khz = video_measurement_.rtp_to_ntp.params().frequency_khz;
     206           0 :   return true;
     207             : }
     208             : 
     209             : }  // namespace webrtc

Generated by: LCOV version 1.13