LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/video - stream_synchronization.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 82 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 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/stream_synchronization.h"
      12             : 
      13             : #include <assert.h>
      14             : #include <math.h>
      15             : #include <stdlib.h>
      16             : 
      17             : #include <algorithm>
      18             : 
      19             : #include "webrtc/base/logging.h"
      20             : 
      21             : namespace webrtc {
      22             : 
      23             : static const int kMaxChangeMs = 80;
      24             : static const int kMaxDeltaDelayMs = 10000;
      25             : static const int kFilterLength = 4;
      26             : // Minimum difference between audio and video to warrant a change.
      27             : static const int kMinDeltaMs = 30;
      28             : 
      29           0 : StreamSynchronization::StreamSynchronization(uint32_t video_primary_ssrc,
      30           0 :                                              int audio_channel_id)
      31             :     : video_primary_ssrc_(video_primary_ssrc),
      32             :       audio_channel_id_(audio_channel_id),
      33             :       base_target_delay_ms_(0),
      34           0 :       avg_diff_ms_(0) {
      35           0 : }
      36             : 
      37           0 : bool StreamSynchronization::ComputeRelativeDelay(
      38             :     const Measurements& audio_measurement,
      39             :     const Measurements& video_measurement,
      40             :     int* relative_delay_ms) {
      41           0 :   assert(relative_delay_ms);
      42             :   int64_t audio_last_capture_time_ms;
      43           0 :   if (!audio_measurement.rtp_to_ntp.Estimate(audio_measurement.latest_timestamp,
      44             :                                              &audio_last_capture_time_ms)) {
      45           0 :     return false;
      46             :   }
      47             :   int64_t video_last_capture_time_ms;
      48           0 :   if (!video_measurement.rtp_to_ntp.Estimate(video_measurement.latest_timestamp,
      49             :                                              &video_last_capture_time_ms)) {
      50           0 :     return false;
      51             :   }
      52           0 :   if (video_last_capture_time_ms < 0) {
      53           0 :     return false;
      54             :   }
      55             :   // Positive diff means that video_measurement is behind audio_measurement.
      56           0 :   *relative_delay_ms = video_measurement.latest_receive_time_ms -
      57           0 :       audio_measurement.latest_receive_time_ms -
      58           0 :       (video_last_capture_time_ms - audio_last_capture_time_ms);
      59           0 :   if (*relative_delay_ms > kMaxDeltaDelayMs ||
      60           0 :       *relative_delay_ms < -kMaxDeltaDelayMs) {
      61           0 :     return false;
      62             :   }
      63           0 :   return true;
      64             : }
      65             : 
      66           0 : bool StreamSynchronization::ComputeDelays(int relative_delay_ms,
      67             :                                           int current_audio_delay_ms,
      68             :                                           int* total_audio_delay_target_ms,
      69             :                                           int* total_video_delay_target_ms) {
      70           0 :   assert(total_audio_delay_target_ms && total_video_delay_target_ms);
      71             : 
      72           0 :   int current_video_delay_ms = *total_video_delay_target_ms;
      73           0 :   LOG(LS_VERBOSE) << "Audio delay: " << current_audio_delay_ms
      74           0 :                   << " current diff: " << relative_delay_ms
      75           0 :                   << " for channel " << audio_channel_id_;
      76             :   // Calculate the difference between the lowest possible video delay and
      77             :   // the current audio delay.
      78           0 :   int current_diff_ms = current_video_delay_ms - current_audio_delay_ms +
      79           0 :       relative_delay_ms;
      80             : 
      81           0 :   avg_diff_ms_ = ((kFilterLength - 1) * avg_diff_ms_ +
      82           0 :       current_diff_ms) / kFilterLength;
      83           0 :   if (abs(avg_diff_ms_) < kMinDeltaMs) {
      84             :     // Don't adjust if the diff is within our margin.
      85           0 :     return false;
      86             :   }
      87             : 
      88             :   // Make sure we don't move too fast.
      89           0 :   int diff_ms = avg_diff_ms_ / 2;
      90           0 :   diff_ms = std::min(diff_ms, kMaxChangeMs);
      91           0 :   diff_ms = std::max(diff_ms, -kMaxChangeMs);
      92             : 
      93             :   // Reset the average after a move to prevent overshooting reaction.
      94           0 :   avg_diff_ms_ = 0;
      95             : 
      96           0 :   if (diff_ms > 0) {
      97             :     // The minimum video delay is longer than the current audio delay.
      98             :     // We need to decrease extra video delay, or add extra audio delay.
      99           0 :     if (channel_delay_.extra_video_delay_ms > base_target_delay_ms_) {
     100             :       // We have extra delay added to ViE. Reduce this delay before adding
     101             :       // extra delay to VoE.
     102           0 :       channel_delay_.extra_video_delay_ms -= diff_ms;
     103           0 :       channel_delay_.extra_audio_delay_ms = base_target_delay_ms_;
     104             :     } else {  // channel_delay_.extra_video_delay_ms > 0
     105             :       // We have no extra video delay to remove, increase the audio delay.
     106           0 :       channel_delay_.extra_audio_delay_ms += diff_ms;
     107           0 :       channel_delay_.extra_video_delay_ms = base_target_delay_ms_;
     108             :     }
     109             :   } else {  // if (diff_ms > 0)
     110             :     // The video delay is lower than the current audio delay.
     111             :     // We need to decrease extra audio delay, or add extra video delay.
     112           0 :     if (channel_delay_.extra_audio_delay_ms > base_target_delay_ms_) {
     113             :       // We have extra delay in VoiceEngine.
     114             :       // Start with decreasing the voice delay.
     115             :       // Note: diff_ms is negative; add the negative difference.
     116           0 :       channel_delay_.extra_audio_delay_ms += diff_ms;
     117           0 :       channel_delay_.extra_video_delay_ms = base_target_delay_ms_;
     118             :     } else {  // channel_delay_.extra_audio_delay_ms > base_target_delay_ms_
     119             :       // We have no extra delay in VoiceEngine, increase the video delay.
     120             :       // Note: diff_ms is negative; subtract the negative difference.
     121           0 :       channel_delay_.extra_video_delay_ms -= diff_ms;  // X - (-Y) = X + Y.
     122           0 :       channel_delay_.extra_audio_delay_ms = base_target_delay_ms_;
     123             :     }
     124             :   }
     125             : 
     126             :   // Make sure that video is never below our target.
     127           0 :   channel_delay_.extra_video_delay_ms = std::max(
     128           0 :       channel_delay_.extra_video_delay_ms, base_target_delay_ms_);
     129             : 
     130             :   int new_video_delay_ms;
     131           0 :   if (channel_delay_.extra_video_delay_ms > base_target_delay_ms_) {
     132           0 :     new_video_delay_ms = channel_delay_.extra_video_delay_ms;
     133             :   } else {
     134             :     // No change to the extra video delay. We are changing audio and we only
     135             :     // allow to change one at the time.
     136           0 :     new_video_delay_ms = channel_delay_.last_video_delay_ms;
     137             :   }
     138             : 
     139             :   // Make sure that we don't go below the extra video delay.
     140           0 :   new_video_delay_ms = std::max(
     141           0 :       new_video_delay_ms, channel_delay_.extra_video_delay_ms);
     142             : 
     143             :   // Verify we don't go above the maximum allowed video delay.
     144           0 :   new_video_delay_ms =
     145           0 :       std::min(new_video_delay_ms, base_target_delay_ms_ + kMaxDeltaDelayMs);
     146             : 
     147             :   int new_audio_delay_ms;
     148           0 :   if (channel_delay_.extra_audio_delay_ms > base_target_delay_ms_) {
     149           0 :     new_audio_delay_ms = channel_delay_.extra_audio_delay_ms;
     150             :   } else {
     151             :     // No change to the audio delay. We are changing video and we only
     152             :     // allow to change one at the time.
     153           0 :     new_audio_delay_ms = channel_delay_.last_audio_delay_ms;
     154             :   }
     155             : 
     156             :   // Make sure that we don't go below the extra audio delay.
     157           0 :   new_audio_delay_ms = std::max(
     158           0 :       new_audio_delay_ms, channel_delay_.extra_audio_delay_ms);
     159             : 
     160             :   // Verify we don't go above the maximum allowed audio delay.
     161           0 :   new_audio_delay_ms =
     162           0 :       std::min(new_audio_delay_ms, base_target_delay_ms_ + kMaxDeltaDelayMs);
     163             : 
     164             :   // Remember our last audio and video delays.
     165           0 :   channel_delay_.last_video_delay_ms = new_video_delay_ms;
     166           0 :   channel_delay_.last_audio_delay_ms = new_audio_delay_ms;
     167             : 
     168           0 :   LOG(LS_VERBOSE) << "Sync video delay " << new_video_delay_ms
     169           0 :                   << " for video primary SSRC " << video_primary_ssrc_
     170           0 :                   << " and audio delay " << channel_delay_.extra_audio_delay_ms
     171           0 :                   << " for audio channel " << audio_channel_id_;
     172             : 
     173             :   // Return values.
     174           0 :   *total_video_delay_target_ms = new_video_delay_ms;
     175           0 :   *total_audio_delay_target_ms = new_audio_delay_ms;
     176           0 :   return true;
     177             : }
     178             : 
     179           0 : void StreamSynchronization::SetTargetBufferingDelay(int target_delay_ms) {
     180             :   // Initial extra delay for audio (accounting for existing extra delay).
     181           0 :   channel_delay_.extra_audio_delay_ms +=
     182           0 :       target_delay_ms - base_target_delay_ms_;
     183           0 :   channel_delay_.last_audio_delay_ms +=
     184           0 :       target_delay_ms - base_target_delay_ms_;
     185             : 
     186             :   // The video delay is compared to the last value (and how much we can update
     187             :   // is limited by that as well).
     188           0 :   channel_delay_.last_video_delay_ms +=
     189           0 :       target_delay_ms - base_target_delay_ms_;
     190             : 
     191           0 :   channel_delay_.extra_video_delay_ms +=
     192           0 :       target_delay_ms - base_target_delay_ms_;
     193             : 
     194             :   // Video is already delayed by the desired amount.
     195           0 :   base_target_delay_ms_ = target_delay_ms;
     196           0 : }
     197             : 
     198             : }  // namespace webrtc

Generated by: LCOV version 1.13