// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_MEDIA_DRIVERS_AMLOGIC_DECODER_H264_MULTI_DECODER_H_
#define SRC_MEDIA_DRIVERS_AMLOGIC_DECODER_H264_MULTI_DECODER_H_

#include <list>
#include <unordered_map>
#include <vector>

#include "macros.h"
#include "media/video/h264_parser.h"
#include "media/video/h264_poc.h"
#include "registers.h"
#include "video_decoder.h"

class MultiAccelerator;
namespace media {
class H264Decoder;
class H264DPB;
struct H264PPS;
class H264Picture;
struct H264SPS;
class DecoderBuffer;
}  // namespace media

// An H264 decoder that can be context-switched in and out.
class H264MultiDecoder : public VideoDecoder {
 public:
  struct ReferenceFrame {
    bool in_use = false;
    bool in_internal_use = false;
    uint32_t index;
    std::shared_ptr<VideoFrame> frame;
    std::unique_ptr<CanvasEntry> y_canvas;
    std::unique_ptr<CanvasEntry> uv_canvas;

    // TODO (use one per reference frame, rather than one per DPB frame)
    InternalBuffer reference_mv_buffer;

    uint32_t info0{};
    uint32_t info1{};
    uint32_t info2{};
    bool is_long_term_reference{};
  };
  struct SliceData {
    media::H264SPS sps;
    media::H264PPS pps;
    media::H264SliceHeader header;
    std::shared_ptr<media::H264Picture> pic;
    std::vector<std::shared_ptr<media::H264Picture>> ref_pic_list0;
    std::vector<std::shared_ptr<media::H264Picture>> ref_pic_list1;
  };
  struct DataInput {
    std::vector<uint8_t> data;
    std::optional<uint64_t> pts;
  };
  class FrameDataProvider {
   public:
    // Called with the video_decoder_lock held.
    virtual DataInput ReadMoreInputData(H264MultiDecoder* decoder) = 0;
    virtual bool HasMoreInputData() = 0;
    virtual void AsyncResetStreamAfterCurrentFrame() = 0;
  };

  H264MultiDecoder(Owner* owner, Client* client, FrameDataProvider* frame_data_provider,
                   bool is_secure);
  H264MultiDecoder(const H264MultiDecoder&) = delete;

  ~H264MultiDecoder() override;

  [[nodiscard]] zx_status_t Initialize() override;
  [[nodiscard]] zx_status_t InitializeHardware() override;
  void HandleInterrupt() override;
  void ReturnFrame(std::shared_ptr<VideoFrame> frame) override;
  void CallErrorHandler() override;
  // PumpOrReschedule must be called after InitializedFrames to get the decoder to continue.
  void InitializedFrames(std::vector<CodecFrame> frames, uint32_t width, uint32_t height,
                         uint32_t stride) override;
  [[nodiscard]] bool CanBeSwappedIn() override;
  [[nodiscard]] bool CanBeSwappedOut() const override;
  void SetSwappedOut() override;
  void SwappedIn() override;
  void OnSignaledWatchdog() override;
  zx_status_t SetupProtection() override;

  zx_status_t InitializeBuffers();

  // Signal that a the end of a stream has been reached. This will flush all frames after decoding
  // all existing frames.
  void QueueInputEos();
  void ReceivedNewInput();
  void FlushFrames();
  void DumpStatus();
  // Try to pump the decoder, rescheduling it if it isn't currently scheduled in.
  void PumpOrReschedule();

  // For use by MultiAccelerator.
  void SubmitDataToHardware(const uint8_t* data, size_t length);
  void SubmitSliceData(SliceData data);
  void SubmitFrameMetadata(ReferenceFrame* reference_frame, const media::H264SPS* sps,
                           const media::H264PPS* pps, const media::H264DPB& dpb);
  void OutputFrame(ReferenceFrame* reference_frame, uint32_t pts_id);
  void StartFrameDecode();
  std::shared_ptr<ReferenceFrame> GetUnusedReferenceFrame();
  bool currently_decoding() { return currently_decoding_; }

  void* SecondaryFirmwareVirtualAddressForTesting() { return secondary_firmware_->virt_base(); }
  void set_use_parser(bool use_parser) { use_parser_ = use_parser; }

 private:
  enum class DecoderState {
    // The hardware's state doesn't reflect that of the H264MultiDecoder.
    kSwappedOut,

    kInitialWaitingForInput,
    kStoppedWaitingForInput,
    kWaitingForConfigChange,
    kRunning,
  };
  zx_status_t LoadSecondaryFirmware(const uint8_t* data, uint32_t firmware_size);
  void ResetHardware();
  void ConfigureDpb();
  void HandleSliceHeadDone();
  void HandlePicDataDone();
  void OnFatalError();
  void PumpDecoder();
  bool InitializeRefPics(const std::vector<std::shared_ptr<media::H264Picture>>& ref_pic_list,
                         uint32_t reg_offset);
  void StartConfigChange();
  // Output all the frames in frames_to_output.
  void OutputReadyFrames();
  void PropagatePotentialEos();
  void HandleHardwareError();
  // This method should be called when the decoder detects an error with the input stream and
  // requires that the decoder is torn down and recreated before continuing. The method will try to
  // reschedule, since the decoder can't do any more work.
  void RequestStreamReset();

  FrameDataProvider* frame_data_provider_;
  bool fatal_error_ = false;
  bool input_eos_queued_ = false;
  bool sent_output_eos_to_client_ = false;
  bool use_parser_ = false;

  std::unique_ptr<media::H264Decoder> media_decoder_;
  std::unique_ptr<media::DecoderBuffer> current_decoder_buffer_;

  std::optional<InternalBuffer> firmware_;
  std::optional<InternalBuffer> secondary_firmware_;
  std::optional<InternalBuffer> codec_data_;
  std::optional<InternalBuffer> aux_buf_;
  std::optional<InternalBuffer> lmem_;

  DecoderState state_ = DecoderState::kSwappedOut;

  uint32_t next_max_reference_size_ = 0u;
  uint32_t display_width_ = 0;
  uint32_t display_height_ = 0;
  uint32_t mb_width_ = 0;
  uint32_t mb_height_ = 0;
  bool waiting_for_surfaces_ = false;
  bool currently_decoding_ = false;
  // This is true if media_decoder_ notified us about the config change, but the client hasn't yet
  // been requested to provide new frames.
  bool pending_config_change_ = false;
  bool in_pump_decoder_ = false;

  std::vector<std::shared_ptr<ReferenceFrame>> video_frames_;
  ReferenceFrame* current_frame_ = nullptr;
  ReferenceFrame* current_metadata_frame_ = nullptr;

  std::list<uint32_t> frames_to_output_;
  std::list<SliceData> slice_data_list_;
  media::H264POC poc_;
  bool have_initialized_ = false;
  uint32_t seq_info2_{};
  // This is the index of the next bitstream id to be assigned to an input buffer.
  uint32_t next_pts_id_{};

  // |id_to_pts_map_| maps from bitstream ids to PTSes. Bitstream IDs are assigned to input buffers
  // and media::H264Decoder plumbs them through to the resulting H264Pictures.
  std::unordered_map<uint32_t, uint64_t> id_to_pts_map_;
};

#endif  // SRC_MEDIA_DRIVERS_AMLOGIC_DECODER_H264_MULTI_DECODER_H_
