/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/video/stream_synchronization.h"

#include <assert.h>
#include <math.h>
#include <stdlib.h>

#include <algorithm>

#include "webrtc/base/logging.h"

namespace webrtc {

static const int kMaxChangeMs = 80;
static const int kMaxDeltaDelayMs = 10000;
static const int kFilterLength = 4;
// Minimum difference between audio and video to warrant a change.
static const int kMinDeltaMs = 30;

StreamSynchronization::StreamSynchronization(uint32_t video_primary_ssrc,
                                             int audio_channel_id)
    : video_primary_ssrc_(video_primary_ssrc),
      audio_channel_id_(audio_channel_id),
      base_target_delay_ms_(0),
      avg_diff_ms_(0) {
}

bool StreamSynchronization::ComputeRelativeDelay(
    const Measurements& audio_measurement,
    const Measurements& video_measurement,
    int* relative_delay_ms) {
  assert(relative_delay_ms);
  int64_t audio_last_capture_time_ms;
  if (!RtpToNtpMs(audio_measurement.latest_timestamp,
                  audio_measurement.rtcp,
                  &audio_last_capture_time_ms)) {
    return false;
  }
  int64_t video_last_capture_time_ms;
  if (!RtpToNtpMs(video_measurement.latest_timestamp,
                  video_measurement.rtcp,
                  &video_last_capture_time_ms)) {
    return false;
  }
  if (video_last_capture_time_ms < 0) {
    return false;
  }
  // Positive diff means that video_measurement is behind audio_measurement.
  *relative_delay_ms = video_measurement.latest_receive_time_ms -
      audio_measurement.latest_receive_time_ms -
      (video_last_capture_time_ms - audio_last_capture_time_ms);
  if (*relative_delay_ms > kMaxDeltaDelayMs ||
      *relative_delay_ms < -kMaxDeltaDelayMs) {
    return false;
  }
  return true;
}

bool StreamSynchronization::ComputeDelays(int relative_delay_ms,
                                          int current_audio_delay_ms,
                                          int* total_audio_delay_target_ms,
                                          int* total_video_delay_target_ms) {
  assert(total_audio_delay_target_ms && total_video_delay_target_ms);

  int current_video_delay_ms = *total_video_delay_target_ms;
  LOG(LS_VERBOSE) << "Audio delay: " << current_audio_delay_ms
                  << " current diff: " << relative_delay_ms
                  << " for channel " << audio_channel_id_;
  // Calculate the difference between the lowest possible video delay and
  // the current audio delay.
  int current_diff_ms = current_video_delay_ms - current_audio_delay_ms +
      relative_delay_ms;

  avg_diff_ms_ = ((kFilterLength - 1) * avg_diff_ms_ +
      current_diff_ms) / kFilterLength;
  if (abs(avg_diff_ms_) < kMinDeltaMs) {
    // Don't adjust if the diff is within our margin.
    return false;
  }

  // Make sure we don't move too fast.
  int diff_ms = avg_diff_ms_ / 2;
  diff_ms = std::min(diff_ms, kMaxChangeMs);
  diff_ms = std::max(diff_ms, -kMaxChangeMs);

  // Reset the average after a move to prevent overshooting reaction.
  avg_diff_ms_ = 0;

  if (diff_ms > 0) {
    // The minimum video delay is longer than the current audio delay.
    // We need to decrease extra video delay, or add extra audio delay.
    if (channel_delay_.extra_video_delay_ms > base_target_delay_ms_) {
      // We have extra delay added to ViE. Reduce this delay before adding
      // extra delay to VoE.
      channel_delay_.extra_video_delay_ms -= diff_ms;
      channel_delay_.extra_audio_delay_ms = base_target_delay_ms_;
    } else {  // channel_delay_.extra_video_delay_ms > 0
      // We have no extra video delay to remove, increase the audio delay.
      channel_delay_.extra_audio_delay_ms += diff_ms;
      channel_delay_.extra_video_delay_ms = base_target_delay_ms_;
    }
  } else {  // if (diff_ms > 0)
    // The video delay is lower than the current audio delay.
    // We need to decrease extra audio delay, or add extra video delay.
    if (channel_delay_.extra_audio_delay_ms > base_target_delay_ms_) {
      // We have extra delay in VoiceEngine.
      // Start with decreasing the voice delay.
      // Note: diff_ms is negative; add the negative difference.
      channel_delay_.extra_audio_delay_ms += diff_ms;
      channel_delay_.extra_video_delay_ms = base_target_delay_ms_;
    } else {  // channel_delay_.extra_audio_delay_ms > base_target_delay_ms_
      // We have no extra delay in VoiceEngine, increase the video delay.
      // Note: diff_ms is negative; subtract the negative difference.
      channel_delay_.extra_video_delay_ms -= diff_ms;  // X - (-Y) = X + Y.
      channel_delay_.extra_audio_delay_ms = base_target_delay_ms_;
    }
  }

  // Make sure that video is never below our target.
  channel_delay_.extra_video_delay_ms = std::max(
      channel_delay_.extra_video_delay_ms, base_target_delay_ms_);

  int new_video_delay_ms;
  if (channel_delay_.extra_video_delay_ms > base_target_delay_ms_) {
    new_video_delay_ms = channel_delay_.extra_video_delay_ms;
  } else {
    // No change to the extra video delay. We are changing audio and we only
    // allow to change one at the time.
    new_video_delay_ms = channel_delay_.last_video_delay_ms;
  }

  // Make sure that we don't go below the extra video delay.
  new_video_delay_ms = std::max(
      new_video_delay_ms, channel_delay_.extra_video_delay_ms);

  // Verify we don't go above the maximum allowed video delay.
  new_video_delay_ms =
      std::min(new_video_delay_ms, base_target_delay_ms_ + kMaxDeltaDelayMs);

  int new_audio_delay_ms;
  if (channel_delay_.extra_audio_delay_ms > base_target_delay_ms_) {
    new_audio_delay_ms = channel_delay_.extra_audio_delay_ms;
  } else {
    // No change to the audio delay. We are changing video and we only
    // allow to change one at the time.
    new_audio_delay_ms = channel_delay_.last_audio_delay_ms;
  }

  // Make sure that we don't go below the extra audio delay.
  new_audio_delay_ms = std::max(
      new_audio_delay_ms, channel_delay_.extra_audio_delay_ms);

  // Verify we don't go above the maximum allowed audio delay.
  new_audio_delay_ms =
      std::min(new_audio_delay_ms, base_target_delay_ms_ + kMaxDeltaDelayMs);

  // Remember our last audio and video delays.
  channel_delay_.last_video_delay_ms = new_video_delay_ms;
  channel_delay_.last_audio_delay_ms = new_audio_delay_ms;

  LOG(LS_VERBOSE) << "Sync video delay " << new_video_delay_ms
                  << " for video primary SSRC " << video_primary_ssrc_
                  << " and audio delay " << channel_delay_.extra_audio_delay_ms
                  << " for audio channel " << audio_channel_id_;

  // Return values.
  *total_video_delay_target_ms = new_video_delay_ms;
  *total_audio_delay_target_ms = new_audio_delay_ms;
  return true;
}

void StreamSynchronization::SetTargetBufferingDelay(int target_delay_ms) {
  // Initial extra delay for audio (accounting for existing extra delay).
  channel_delay_.extra_audio_delay_ms +=
      target_delay_ms - base_target_delay_ms_;
  channel_delay_.last_audio_delay_ms +=
      target_delay_ms - base_target_delay_ms_;

  // The video delay is compared to the last value (and how much we can update
  // is limited by that as well).
  channel_delay_.last_video_delay_ms +=
      target_delay_ms - base_target_delay_ms_;

  channel_delay_.extra_video_delay_ms +=
      target_delay_ms - base_target_delay_ms_;

  // Video is already delayed by the desired amount.
  base_target_delay_ms_ = target_delay_ms;
}

}  // namespace webrtc
