/*
 *  Copyright (c) 2014 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 MEDIA_ENGINE_SIMULCAST_ENCODER_ADAPTER_H_
#define MEDIA_ENGINE_SIMULCAST_ENCODER_ADAPTER_H_

#include <atomic>
#include <bitset>
#include <cstddef>
#include <cstdint>
#include <deque>
#include <list>
#include <memory>
#include <optional>
#include <vector>

#include "absl/base/nullability.h"
#include "api/environment/environment.h"
#include "api/fec_controller_override.h"
#include "api/sequence_checker.h"
#include "api/units/timestamp.h"
#include "api/video/encoded_image.h"
#include "api/video/video_codec_constants.h"
#include "api/video/video_frame.h"
#include "api/video/video_frame_type.h"
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/video_encoder.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "common_video/framerate_controller.h"
#include "modules/video_coding/include/video_codec_interface.h"
#include "rtc_base/experiments/encoder_info_settings.h"
#include "rtc_base/synchronization/mutex.h"
#include "rtc_base/system/no_unique_address.h"
#include "rtc_base/system/rtc_export.h"
#include "rtc_base/thread_annotations.h"

namespace webrtc {

// SimulcastEncoderAdapter implements simulcast support by creating multiple
// VideoEncoder instances with the given VideoEncoderFactory.
// The object is created and destroyed on the worker thread, but all public
// interfaces should be called from the encoder task queue.
class RTC_EXPORT SimulcastEncoderAdapter : public VideoEncoder {
 public:
  // `primary_factory` produces the first-choice encoders to use.
  // `fallback_factory`, if non-null, is used to create fallback encoder that
  // will be used if InitEncode() fails for the primary encoder.
  SimulcastEncoderAdapter(const Environment& env,
                          VideoEncoderFactory* absl_nonnull primary_factory,
                          VideoEncoderFactory* absl_nullable fallback_factory,
                          const SdpVideoFormat& format);

  ~SimulcastEncoderAdapter() override;

  // Implements VideoEncoder.
  void SetFecControllerOverride(
      FecControllerOverride* fec_controller_override) override;
  int Release() override;
  int InitEncode(const VideoCodec* codec_settings,
                 const VideoEncoder::Settings& settings) override;
  int Encode(const VideoFrame& input_image,
             const std::vector<VideoFrameType>* frame_types) override;
  int RegisterEncodeCompleteCallback(EncodedImageCallback* callback) override;
  void SetRates(const RateControlParameters& parameters) override;
  void OnPacketLossRateUpdate(float packet_loss_rate) override;
  void OnRttUpdate(int64_t rtt_ms) override;
  void OnLossNotification(const LossNotification& loss_notification) override;

  EncoderInfo GetEncoderInfo() const override;

 protected:
  void DestroyStoredEncoders();

 private:
  class EncoderContext {
   public:
    EncoderContext(std::unique_ptr<VideoEncoder> encoder,
                   bool prefer_temporal_support,
                   VideoEncoder::EncoderInfo primary_info,
                   VideoEncoder::EncoderInfo fallback_info,
                   SdpVideoFormat video_format);
    EncoderContext& operator=(EncoderContext&&) = delete;

    VideoEncoder& encoder() { return *encoder_; }
    bool prefer_temporal_support() { return prefer_temporal_support_; }
    void Release();

    const VideoEncoder::EncoderInfo& PrimaryInfo() { return primary_info_; }

    const VideoEncoder::EncoderInfo& FallbackInfo() { return fallback_info_; }

    const SdpVideoFormat& video_format() { return video_format_; }

   private:
    std::unique_ptr<VideoEncoder> encoder_;
    bool prefer_temporal_support_;
    const VideoEncoder::EncoderInfo primary_info_;
    const VideoEncoder::EncoderInfo fallback_info_;
    const SdpVideoFormat video_format_;
  };

  class StreamContext : public EncodedImageCallback {
   public:
    StreamContext(SimulcastEncoderAdapter* parent,
                  std::unique_ptr<EncoderContext> encoder_context,
                  std::unique_ptr<FramerateController> framerate_controller,
                  int stream_idx,
                  uint16_t width,
                  uint16_t height,
                  bool send_stream);
    StreamContext(StreamContext&& rhs);
    StreamContext& operator=(StreamContext&&) = delete;
    ~StreamContext() override;

    Result OnEncodedImage(
        const EncodedImage& encoded_image,
        const CodecSpecificInfo* codec_specific_info) override;
    void OnFrameDropped(uint32_t rtp_timestamp,
                        int spatial_id,
                        bool is_end_of_temporal_unit) override;

    int Encode(const VideoFrame& frame,
               const std::vector<VideoFrameType>* frame_types);
    VideoEncoder& encoder() { return encoder_context_->encoder(); }
    const VideoEncoder& encoder() const { return encoder_context_->encoder(); }

    int stream_idx() const { return stream_idx_; }
    uint16_t width() const { return width_; }
    uint16_t height() const { return height_; }
    bool is_keyframe_needed() const {
      return !is_paused_ && is_keyframe_needed_;
    }
    void set_is_keyframe_needed() { is_keyframe_needed_ = true; }
    bool is_paused() const { return is_paused_; }
    void set_is_paused(bool is_paused) { is_paused_ = is_paused; }
    std::optional<double> target_fps() const {
      return framerate_controller_ == nullptr
                 ? std::nullopt
                 : std::optional<double>(
                       framerate_controller_->GetMaxFramerate());
    }

    std::unique_ptr<EncoderContext> ReleaseEncoderContext() &&;
    void OnKeyframe(Timestamp timestamp);
    bool ShouldDropFrame(Timestamp timestamp);

   private:
    void MaybeCullOldTimestamps(uint32_t new_rtp_timestamp);

    SimulcastEncoderAdapter* const parent_;
    std::unique_ptr<EncoderContext> encoder_context_;
    std::unique_ptr<FramerateController> framerate_controller_;
    mutable Mutex queue_mutex_;
    std::deque<uint32_t> pending_rtp_timestamps_ RTC_GUARDED_BY(queue_mutex_);
    const int stream_idx_;
    const uint16_t width_;
    const uint16_t height_;
    bool is_keyframe_needed_;
    bool is_paused_;
  };

  struct PendingFrame {
    uint32_t rtp_timestamp;
    // Bitmask of expected stream indices (1 << stream_idx).
    std::bitset<kMaxSimulcastStreams> expected_layer_index;
  };

  bool Initialized() const;

  // This method creates encoder. May reuse previously created encoders from
  // `cached_encoder_contexts_`. It's const because it's used from
  // const GetEncoderInfo().
  std::unique_ptr<EncoderContext> FetchOrCreateEncoderContext(
      bool is_lowest_quality_stream,
      std::optional<int> stream_idx) const;

  VideoCodec MakeStreamCodec(const VideoCodec& codec,
                             int stream_idx,
                             uint32_t start_bitrate_kbps,
                             bool is_lowest_quality_stream,
                             bool is_highest_quality_stream);

  EncodedImageCallback::Result OnEncodedImage(
      size_t stream_idx,
      const EncodedImage& encoded_image,
      const CodecSpecificInfo* codec_specific_info);

  void OnFrameDropped(uint32_t rtp_timestamp, int spatial_id);

  void OverrideFromFieldTrial(VideoEncoder::EncoderInfo* info) const;

  const Environment env_;
  std::atomic<int> inited_;
  VideoEncoderFactory* const primary_encoder_factory_;
  VideoEncoderFactory* const fallback_encoder_factory_;
  const SdpVideoFormat video_format_;
  VideoCodec codec_;
  int total_streams_count_;
  bool bypass_mode_;
  std::vector<StreamContext> stream_contexts_;
  EncodedImageCallback* encoded_complete_callback_;

  // TODO: webrtc:467444018 - Remove this mutex and post any callback to
  // OnEncodedImage/OnFrameDropped to the encoder queue instead if not already
  // on it.
  mutable Mutex pending_frames_mutex_;
  // A queue of pending frames for which we have not yet received a callback
  // (either an encoded frame or frame drop notification), sorted by their
  // RTP timestamp.
  std::deque<PendingFrame> pending_frames_
      RTC_GUARDED_BY(pending_frames_mutex_);

  // Used for checking the single-threaded access of the encoder interface.
  RTC_NO_UNIQUE_ADDRESS SequenceChecker encoder_queue_checker_;

  // Store previously created and released encoders , so they don't have to be
  // recreated. Remaining encoders are destroyed by the destructor.
  // Marked as `mutable` becuase we may need to temporarily create encoder in
  // GetEncoderInfo(), which is const.
  mutable std::list<std::unique_ptr<EncoderContext>> cached_encoder_contexts_;

  const bool boost_base_layer_quality_;
  const bool prefer_temporal_support_on_base_layer_;
  const bool per_layer_pli_;
  const bool drop_unaligned_resolution_;

  const SimulcastEncoderAdapterEncoderInfoSettings encoder_info_override_;
};

}  // namespace webrtc

#endif  // MEDIA_ENGINE_SIMULCAST_ENCODER_ADAPTER_H_
