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

#include <stdint.h>

#include <functional>
#include <memory>
#include <set>
#include <utility>

#include "absl/types/optional.h"
#include "api/metronome/metronome.h"
#include "api/sequence_checker.h"
#include "api/task_queue/task_queue_base.h"
#include "api/units/timestamp.h"
#include "rtc_base/checks.h"
#include "rtc_base/thread_annotations.h"
#include "video/frame_decode_scheduler.h"
#include "video/frame_decode_timing.h"

namespace webrtc {

// DecodeSynchronizer synchronizes the frame scheduling by coalescing decoding
// on the metronome.
//
// A video receive stream can use the DecodeSynchronizer by receiving a
// FrameDecodeScheduler instance with `CreateSynchronizedFrameScheduler()`.
// This instance implements FrameDecodeScheduler and can be used as a normal
// scheduler. This instance is owned by the receive stream, and is borrowed by
// the DecodeSynchronizer. The DecodeSynchronizer will stop borrowing the
// instance when `FrameDecodeScheduler::Stop()` is called, after which the
// scheduler may be destroyed by the receive stream.
//
// When a frame is scheduled for decode by a receive stream using the
// DecodeSynchronizer, it will instead be executed on the metronome during the
// tick interval where `max_decode_time` occurs. For example, if a frame is
// scheduled for decode in 50ms and the tick interval is 20ms, then the frame
// will be released for decoding in 2 ticks. See below for illustration,
//
// In the case where the decode time is in the past, or must occur before the
// next metronome tick then the frame will be released right away, allowing a
// delayed stream to catch up quickly.
//
// DecodeSynchronizer is single threaded - all method calls must run on the
// `worker_queue_`.
class DecodeSynchronizer : private Metronome::TickListener {
 public:
  DecodeSynchronizer(Clock* clock,
                     Metronome* metronome,
                     TaskQueueBase* worker_queue);
  ~DecodeSynchronizer() override;
  DecodeSynchronizer(const DecodeSynchronizer&) = delete;
  DecodeSynchronizer& operator=(const DecodeSynchronizer&) = delete;

  std::unique_ptr<FrameDecodeScheduler> CreateSynchronizedFrameScheduler();

 private:
  class ScheduledFrame {
   public:
    ScheduledFrame(uint32_t rtp_timestamp,
                   FrameDecodeTiming::FrameSchedule schedule,
                   FrameDecodeScheduler::FrameReleaseCallback callback);

    // Disallow copy since `callback` should only be moved.
    ScheduledFrame(const ScheduledFrame&) = delete;
    ScheduledFrame& operator=(const ScheduledFrame&) = delete;
    ScheduledFrame(ScheduledFrame&&) = default;
    ScheduledFrame& operator=(ScheduledFrame&&) = default;

    // Executes `callback_`.
    void RunFrameReleaseCallback() &&;

    uint32_t rtp_timestamp() const { return rtp_timestamp_; }
    Timestamp LatestDecodeTime() const;

   private:
    uint32_t rtp_timestamp_;
    FrameDecodeTiming::FrameSchedule schedule_;
    FrameDecodeScheduler::FrameReleaseCallback callback_;
  };

  class SynchronizedFrameDecodeScheduler : public FrameDecodeScheduler {
   public:
    explicit SynchronizedFrameDecodeScheduler(DecodeSynchronizer* sync);
    ~SynchronizedFrameDecodeScheduler() override;

    // Releases the outstanding frame for decoding. This invalidates
    // `next_frame_`. There must be a frame scheduled.
    ScheduledFrame ReleaseNextFrame();

    // Returns `next_frame_.schedule.max_decode_time`. There must be a frame
    // scheduled when this is called.
    Timestamp LatestDecodeTime();

    // FrameDecodeScheduler implementation.
    absl::optional<uint32_t> ScheduledRtpTimestamp() override;
    void ScheduleFrame(uint32_t rtp,
                       FrameDecodeTiming::FrameSchedule schedule,
                       FrameReleaseCallback cb) override;
    void CancelOutstanding() override;
    void Stop() override;

   private:
    DecodeSynchronizer* sync_;
    absl::optional<ScheduledFrame> next_frame_;
    bool stopped_ = false;
  };

  void OnFrameScheduled(SynchronizedFrameDecodeScheduler* scheduler);
  void RemoveFrameScheduler(SynchronizedFrameDecodeScheduler* scheduler);

  // Metronome::TickListener implementation.
  void OnTick() override;
  TaskQueueBase* OnTickTaskQueue() override;

  Clock* const clock_;
  TaskQueueBase* const worker_queue_;
  Metronome* const metronome_;

  Timestamp expected_next_tick_ = Timestamp::PlusInfinity();
  std::set<SynchronizedFrameDecodeScheduler*> schedulers_
      RTC_GUARDED_BY(worker_queue_);
};

}  // namespace webrtc

#endif  // VIDEO_DECODE_SYNCHRONIZER_H_
