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

// Windows specific implementation of VideoCaptureDevice.
// MediaFoundation is used for capturing. MediaFoundation provides its own
// threads for capturing.

#ifndef MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_MF_WIN_H_
#define MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_MF_WIN_H_

#include <mfcaptureengine.h>
#include <mfidl.h>
#include <mfreadwrite.h>
#include <stdint.h>
#include <strmif.h>
#include <wrl/client.h>

#include <vector>

#include "base/callback_forward.h"
#include "base/containers/queue.h"
#include "base/macros.h"
#include "base/sequence_checker.h"
#include "media/base/win/dxgi_device_manager.h"
#include "media/capture/capture_export.h"
#include "media/capture/video/video_capture_device.h"
#include "media/capture/video/win/capability_list_win.h"
#include "media/capture/video/win/metrics.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

interface IMFSourceReader;

namespace base {
class Location;
}  // namespace base

namespace media {

class MFVideoCallback;

class CAPTURE_EXPORT VideoCaptureDeviceMFWin : public VideoCaptureDevice {
 public:
  static bool GetPixelFormatFromMFSourceMediaSubtype(const GUID& guid,
                                                     bool use_hardware_format,
                                                     VideoPixelFormat* format);
  static VideoCaptureControlSupport GetControlSupport(
      Microsoft::WRL::ComPtr<IMFMediaSource> source);

  explicit VideoCaptureDeviceMFWin(
      const VideoCaptureDeviceDescriptor& device_descriptor,
      Microsoft::WRL::ComPtr<IMFMediaSource> source,
      scoped_refptr<DXGIDeviceManager> dxgi_device_manager);
  explicit VideoCaptureDeviceMFWin(
      const VideoCaptureDeviceDescriptor& device_descriptor,
      Microsoft::WRL::ComPtr<IMFMediaSource> source,
      scoped_refptr<DXGIDeviceManager> dxgi_device_manager,
      Microsoft::WRL::ComPtr<IMFCaptureEngine> engine);

  ~VideoCaptureDeviceMFWin() override;

  // Opens the device driver for this device.
  bool Init();

  // VideoCaptureDevice implementation.
  void AllocateAndStart(
      const VideoCaptureParams& params,
      std::unique_ptr<VideoCaptureDevice::Client> client) override;
  void StopAndDeAllocate() override;
  void TakePhoto(TakePhotoCallback callback) override;
  void GetPhotoState(GetPhotoStateCallback callback) override;
  void SetPhotoOptions(mojom::PhotoSettingsPtr settings,
                       SetPhotoOptionsCallback callback) override;
  void OnUtilizationReport(int frame_feedback_id,
                           media::VideoCaptureFeedback feedback) override;

  // Captured new video data.
  void OnIncomingCapturedData(IMFMediaBuffer* buffer,
                              base::TimeTicks reference_time,
                              base::TimeDelta timestamp);
  void OnFrameDropped(VideoCaptureFrameDropReason reason);
  void OnEvent(IMFMediaEvent* media_event);

  using CreateMFPhotoCallbackCB =
      base::RepeatingCallback<scoped_refptr<IMFCaptureEngineOnSampleCallback>(
          VideoCaptureDevice::TakePhotoCallback callback,
          VideoCaptureFormat format)>;

  bool get_use_photo_stream_to_take_photo_for_testing() {
    return !photo_capabilities_.empty();
  }

  void set_create_mf_photo_callback_for_testing(CreateMFPhotoCallbackCB cb) {
    create_mf_photo_callback_ = cb;
  }

  void set_max_retry_count_for_testing(int max_retry_count) {
    max_retry_count_ = max_retry_count;
  }

  void set_retry_delay_in_ms_for_testing(int retry_delay_in_ms) {
    retry_delay_in_ms_ = retry_delay_in_ms;
  }

  void set_dxgi_device_manager_for_testing(
      scoped_refptr<DXGIDeviceManager> dxgi_device_manager) {
    dxgi_device_manager_ = std::move(dxgi_device_manager);
  }

  absl::optional<int> camera_rotation() const { return camera_rotation_; }

 private:
  HRESULT ExecuteHresultCallbackWithRetries(
      base::RepeatingCallback<HRESULT()> callback,
      MediaFoundationFunctionRequiringRetry which_function);
  HRESULT GetDeviceStreamCount(IMFCaptureSource* source, DWORD* count);
  HRESULT GetDeviceStreamCategory(
      IMFCaptureSource* source,
      DWORD stream_index,
      MF_CAPTURE_ENGINE_STREAM_CATEGORY* stream_category);
  HRESULT GetAvailableDeviceMediaType(IMFCaptureSource* source,
                                      DWORD stream_index,
                                      DWORD media_type_index,
                                      IMFMediaType** type);

  HRESULT FillCapabilities(IMFCaptureSource* source,
                           bool photo,
                           CapabilityList* capabilities);
  void OnError(VideoCaptureError error,
               const base::Location& from_here,
               HRESULT hr);
  void OnError(VideoCaptureError error,
               const base::Location& from_here,
               const char* message);
  void SendOnStartedIfNotYetSent();
  HRESULT WaitOnCaptureEvent(GUID capture_event_guid);
  HRESULT DeliverTextureToClient(ID3D11Texture2D* texture,
                                 base::TimeTicks reference_time,
                                 base::TimeDelta timestamp)
      EXCLUSIVE_LOCKS_REQUIRED(lock_);
  void OnIncomingCapturedDataInternal(
      IMFMediaBuffer* buffer,
      base::TimeTicks reference_time,
      base::TimeDelta timestamp,
      VideoCaptureFrameDropReason& frame_drop_reason);

  VideoFacingMode facing_mode_;
  CreateMFPhotoCallbackCB create_mf_photo_callback_;
  scoped_refptr<MFVideoCallback> video_callback_;
  bool is_initialized_;
  int max_retry_count_;
  int retry_delay_in_ms_;

  // Guards the below variables from concurrent access between methods running
  // on |sequence_checker_| and calls to OnIncomingCapturedData() and OnEvent()
  // made by MediaFoundation on threads outside of our control.
  base::Lock lock_;

  std::unique_ptr<VideoCaptureDevice::Client> client_;
  const Microsoft::WRL::ComPtr<IMFMediaSource> source_;
  Microsoft::WRL::ComPtr<IAMCameraControl> camera_control_;
  Microsoft::WRL::ComPtr<IAMVideoProcAmp> video_control_;
  Microsoft::WRL::ComPtr<IMFCaptureEngine> engine_;
  std::unique_ptr<CapabilityWin> selected_video_capability_;
  CapabilityList photo_capabilities_;
  std::unique_ptr<CapabilityWin> selected_photo_capability_;
  bool is_started_;
  bool has_sent_on_started_to_client_;
  // These flags keep the manual/auto mode between cycles of SetPhotoOptions().
  bool exposure_mode_manual_;
  bool focus_mode_manual_;
  bool white_balance_mode_manual_;
  base::queue<TakePhotoCallback> video_stream_take_photo_callbacks_;
  base::WaitableEvent capture_initialize_;
  base::WaitableEvent capture_error_;
  scoped_refptr<DXGIDeviceManager> dxgi_device_manager_;
  absl::optional<int> camera_rotation_;

  media::VideoCaptureFeedback last_feedback_;

  SEQUENCE_CHECKER(sequence_checker_);

  DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureDeviceMFWin);
};

}  // namespace media

#endif  // MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_MF_WIN_H_
