/*
 *  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 "video/encoder_rtcp_feedback.h"

#include <algorithm>
#include <optional>
#include <utility>

#include "api/environment/environment.h"
#include "api/video_codecs/video_encoder.h"
#include "rtc_base/checks.h"
#include "rtc_base/experiments/keyframe_interval_settings.h"
#include "system_wrappers/include/clock.h"

namespace webrtc {

namespace {
constexpr int kMinKeyframeSendIntervalMs = 300;
}  // namespace

EncoderRtcpFeedback::EncoderRtcpFeedback(
    const Environment& env,
    bool per_layer_keyframes,
    const std::vector<uint32_t>& ssrcs,
    VideoStreamEncoderInterface* encoder,
    std::function<std::vector<RtpSequenceNumberMap::Info>(
        uint32_t ssrc,
        const std::vector<uint16_t>& seq_nums)> get_packet_infos)
    : env_(env),
      ssrcs_(ssrcs),
      per_layer_keyframes_(per_layer_keyframes),
      get_packet_infos_(std::move(get_packet_infos)),
      video_stream_encoder_(encoder),
      time_last_packet_delivery_queue_(per_layer_keyframes ? ssrcs.size() : 1,
                                       Timestamp::Zero()),
      min_keyframe_send_interval_(
          TimeDelta::Millis(KeyframeIntervalSettings(env_.field_trials())
                                .MinKeyframeSendIntervalMs()
                                .value_or(kMinKeyframeSendIntervalMs))) {
  RTC_DCHECK(!ssrcs.empty());
  packet_delivery_queue_.Detach();
}

// Called via Call::DeliverRtcp.
void EncoderRtcpFeedback::OnReceivedIntraFrameRequest(uint32_t ssrc) {
  RTC_DCHECK_RUN_ON(&packet_delivery_queue_);
  RTC_DCHECK(std::find(ssrcs_.begin(), ssrcs_.end(), ssrc) != ssrcs_.end());

  auto it = std::find(ssrcs_.begin(), ssrcs_.end(), ssrc);
  if (it == ssrcs_.end()) {
    RTC_LOG(LS_WARNING) << "SSRC " << ssrc << " not found.";
    return;
  }
  size_t ssrc_index =
      per_layer_keyframes_ ? std::distance(ssrcs_.begin(), it) : 0;
  RTC_CHECK_LE(ssrc_index, time_last_packet_delivery_queue_.size());
  const Timestamp now = env_.clock().CurrentTime();
  if (time_last_packet_delivery_queue_[ssrc_index] +
          min_keyframe_send_interval_ >
      now)
    return;

  time_last_packet_delivery_queue_[ssrc_index] = now;

  std::vector<VideoFrameType> layers(ssrcs_.size(),
                                     VideoFrameType::kVideoFrameDelta);
  if (!per_layer_keyframes_) {
    // Always produce key frame for all streams.
    video_stream_encoder_->SendKeyFrame();
  } else {
    // Determine on which layer we ask for key frames.
    layers[ssrc_index] = VideoFrameType::kVideoFrameKey;
    video_stream_encoder_->SendKeyFrame(layers);
  }
}

void EncoderRtcpFeedback::OnReceivedLossNotification(
    uint32_t ssrc,
    uint16_t seq_num_of_last_decodable,
    uint16_t seq_num_of_last_received,
    bool decodability_flag) {
  RTC_DCHECK(get_packet_infos_) << "Object initialization incomplete.";

  const std::vector<uint16_t> seq_nums = {seq_num_of_last_decodable,
                                          seq_num_of_last_received};
  const std::vector<RtpSequenceNumberMap::Info> infos =
      get_packet_infos_(ssrc, seq_nums);
  if (infos.empty()) {
    return;
  }
  RTC_DCHECK_EQ(infos.size(), 2u);

  const RtpSequenceNumberMap::Info& last_decodable = infos[0];
  const RtpSequenceNumberMap::Info& last_received = infos[1];

  VideoEncoder::LossNotification loss_notification;
  loss_notification.timestamp_of_last_decodable = last_decodable.timestamp;
  loss_notification.timestamp_of_last_received = last_received.timestamp;

  // Deduce decodability of the last received frame and of its dependencies.
  if (last_received.is_first && last_received.is_last) {
    // The frame consists of a single packet, and that packet has evidently
    // been received in full; the frame is therefore assemblable.
    // In this case, the decodability of the dependencies is communicated by
    // the decodability flag, and the frame itself is decodable if and only
    // if they are decodable.
    loss_notification.dependencies_of_last_received_decodable =
        decodability_flag;
    loss_notification.last_received_decodable = decodability_flag;
  } else if (last_received.is_first && !last_received.is_last) {
    // In this case, the decodability flag communicates the decodability of
    // the dependencies. If any is undecodable, we also know that the frame
    // itself will not be decodable; if all are decodable, the frame's own
    // decodability will remain unknown, as not all of its packets have
    // been received.
    loss_notification.dependencies_of_last_received_decodable =
        decodability_flag;
    loss_notification.last_received_decodable =
        !decodability_flag ? std::make_optional(false) : std::nullopt;
  } else if (!last_received.is_first && last_received.is_last) {
    if (decodability_flag) {
      // The frame has been received in full, and found to be decodable.
      // (Messages of this type are not sent by WebRTC at the moment, but are
      // theoretically possible, for example for serving as acks.)
      loss_notification.dependencies_of_last_received_decodable = true;
      loss_notification.last_received_decodable = true;
    } else {
      // It is impossible to tell whether some dependencies were undecodable,
      // or whether the frame was unassemblable, but in either case, the frame
      // itself was undecodable.
      loss_notification.dependencies_of_last_received_decodable = std::nullopt;
      loss_notification.last_received_decodable = false;
    }
  } else {  // !last_received.is_first && !last_received.is_last
    if (decodability_flag) {
      // The frame has not yet been received in full, but no gaps have
      // been encountered so far, and the dependencies were all decodable.
      // (Messages of this type are not sent by WebRTC at the moment, but are
      // theoretically possible, for example for serving as acks.)
      loss_notification.dependencies_of_last_received_decodable = true;
      loss_notification.last_received_decodable = std::nullopt;
    } else {
      // It is impossible to tell whether some dependencies were undecodable,
      // or whether the frame was unassemblable, but in either case, the frame
      // itself was undecodable.
      loss_notification.dependencies_of_last_received_decodable = std::nullopt;
      loss_notification.last_received_decodable = false;
    }
  }

  video_stream_encoder_->OnLossNotification(loss_notification);
}

}  // namespace webrtc
