/*
 *  Copyright (c) 2019 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.
 */

#ifndef MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_
#define MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_

#include <set>

#include "absl/types/optional.h"
#include "modules/include/module_common_types.h"
#include "modules/video_coding/packet.h"
#include "rtc_base/numerics/sequence_number_util.h"
#include "rtc_base/sequenced_task_checker.h"

namespace webrtc {

class LossNotificationController {
 public:
  LossNotificationController(KeyFrameRequestSender* key_frame_request_sender,
                             LossNotificationSender* loss_notification_sender);
  ~LossNotificationController();

  // An RTP packet was received from the network.
  void OnReceivedPacket(const VCMPacket& packet);

  // A frame was assembled from packets previously received.
  // (Should be called even if the frame was composed of a single packet.)
  void OnAssembledFrame(uint16_t first_seq_num,
                        uint16_t frame_id,
                        bool discardable,
                        rtc::ArrayView<const uint16_t> frame_dependency_diffs);

 private:
  void DiscardOldInformation();

  bool AllDependenciesDecodable(
      uint64_t unwrapped_frame_id,
      rtc::ArrayView<const uint16_t> frame_dependency_diffs) const;

  // When the loss of a packet or the non-decodability of a frame is detected,
  // produces a key frame request or a loss notification.
  // 1. |last_received_seq_num| is the last received sequence number.
  // 2. |decodability_flag| refers to the frame associated with the last packet.
  //    It is set to |true| if and only if all of that frame's dependencies are
  //    known to be decodable, and the frame itself is not yet known to be
  //    unassemblable (i.e. no earlier parts of it were lost).
  //    Clarifications:
  //    a. In a multi-packet frame, the first packet reveals the frame's
  //       dependencies, but it is not yet known whether all parts of the
  //       current frame will be received.
  //    b. In a multi-packet frame, if the first packet is missed, the
  //       dependencies are unknown, but it is known that the frame itself
  //       is unassemblable.
  void HandleLoss(uint16_t last_received_seq_num, bool decodability_flag);

  KeyFrameRequestSender* const key_frame_request_sender_
      RTC_GUARDED_BY(sequenced_task_checker_);

  LossNotificationSender* const loss_notification_sender_
      RTC_GUARDED_BY(sequenced_task_checker_);

  SeqNumUnwrapper<uint16_t> frame_id_unwrapper_
      RTC_GUARDED_BY(sequenced_task_checker_);

  // Tracked to avoid processing repeated frames (buggy/malicious remote).
  absl::optional<uint64_t> last_received_unwrapped_frame_id_
      RTC_GUARDED_BY(sequenced_task_checker_);

  // Tracked to avoid processing repeated packets.
  absl::optional<uint16_t> last_received_seq_num_
      RTC_GUARDED_BY(sequenced_task_checker_);

  // Tracked in order to correctly report the potential-decodability of
  // multi-packet frames.
  bool current_frame_potentially_decodable_
      RTC_GUARDED_BY(sequenced_task_checker_);

  // Loss notifications contain the sequence number of the first packet of
  // the last decodable-and-non-discardable frame. Since this is a bit of
  // a mouthful, last_decodable_non_discardable_.first_seq_num is used,
  // which hopefully is a bit easier for human beings to parse
  // than |first_seq_num_of_last_decodable_non_discardable_|.
  struct FrameInfo {
    explicit FrameInfo(uint16_t first_seq_num) : first_seq_num(first_seq_num) {}
    uint16_t first_seq_num;
  };
  absl::optional<FrameInfo> last_decodable_non_discardable_
      RTC_GUARDED_BY(sequenced_task_checker_);

  // Track which frames are decodable. Later frames are also decodable if
  // all of their dependencies can be found in this container.
  // (Naturally, later frames must also be assemblable to be decodable.)
  std::set<uint64_t> decodable_unwrapped_frame_ids_
      RTC_GUARDED_BY(sequenced_task_checker_);

  rtc::SequencedTaskChecker sequenced_task_checker_;
};

}  // namespace webrtc

#endif  // MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_
