// 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. DirectShow is used for
// capturing. DirectShow provide its own threads for capturing.

#ifndef MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_WIN_H_
#define MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_WIN_H_

// Avoid including strsafe.h via dshow as it will cause build warnings.
#define NO_DSHOW_STRSAFE
#include <dshow.h>
#include <stdint.h>
#include <vidcap.h>
#include <wrl/client.h>

#include <map>
#include <string>

#include "base/containers/queue.h"
#include "base/macros.h"
#include "base/threading/thread_checker.h"
#include "media/capture/video/video_capture_device.h"
#include "media/capture/video/win/capability_list_win.h"
#include "media/capture/video/win/sink_filter_win.h"
#include "media/capture/video/win/sink_input_pin_win.h"
#include "media/capture/video_capture_types.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace base {
class Location;
}  // namespace base

namespace media {

// All the methods in the class can only be run on a COM initialized thread.
class VideoCaptureDeviceWin : public VideoCaptureDevice,
                              public SinkFilterObserver {
 public:
  // A utility class that wraps the AM_MEDIA_TYPE type and guarantees that
  // we free the structure when exiting the scope.  DCHECKing is also done to
  // avoid memory leaks.
  class ScopedMediaType {
   public:
    ScopedMediaType() : media_type_(nullptr) {}
    ~ScopedMediaType() { Free(); }

    AM_MEDIA_TYPE* operator->() { return media_type_; }
    AM_MEDIA_TYPE* get() { return media_type_; }
    void Free();
    AM_MEDIA_TYPE** Receive();

   private:
    void FreeMediaType(AM_MEDIA_TYPE* mt);
    void DeleteMediaType(AM_MEDIA_TYPE* mt);

    AM_MEDIA_TYPE* media_type_;
  };

  static VideoCaptureControlSupport GetControlSupport(
      Microsoft::WRL::ComPtr<IBaseFilter> capture_filter);
  static void GetDeviceCapabilityList(
      Microsoft::WRL::ComPtr<IBaseFilter> capture_filter,
      bool query_detailed_frame_rates,
      CapabilityList* out_capability_list);
  static void GetPinCapabilityList(
      Microsoft::WRL::ComPtr<IBaseFilter> capture_filter,
      Microsoft::WRL::ComPtr<IPin> output_capture_pin,
      bool query_detailed_frame_rates,
      CapabilityList* out_capability_list);
  static Microsoft::WRL::ComPtr<IPin> GetPin(
      Microsoft::WRL::ComPtr<IBaseFilter> capture_filter,
      PIN_DIRECTION pin_dir,
      REFGUID category,
      REFGUID major_type);
  static VideoPixelFormat TranslateMediaSubtypeToPixelFormat(
      const GUID& sub_type);

  VideoCaptureDeviceWin(const VideoCaptureDeviceDescriptor& device_descriptor,
                        Microsoft::WRL::ComPtr<IBaseFilter> capture_filter);
  ~VideoCaptureDeviceWin() 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;

 private:
  enum InternalState {
    kIdle,       // The device driver is opened but camera is not in use.
    kCapturing,  // Video is being captured.
    kError       // Error accessing HW functions.
                 // User needs to recover by destroying the object.
  };

  static bool GetCameraAndVideoControls(
      Microsoft::WRL::ComPtr<IBaseFilter> capture_filter,
      ICameraControl** camera_control,
      IVideoProcAmp** video_control);

  // Implements SinkFilterObserver.
  void FrameReceived(const uint8_t* buffer,
                     int length,
                     const VideoCaptureFormat& format,
                     base::TimeDelta timestamp,
                     bool flip_y) override;
  void FrameDropped(VideoCaptureFrameDropReason reason) override;

  bool CreateCapabilityMap();
  void SetAntiFlickerInCaptureFilter(const VideoCaptureParams& params);
  void SetErrorState(media::VideoCaptureError error,
                     const base::Location& from_here,
                     const std::string& reason,
                     HRESULT hr);

  const VideoCaptureDeviceDescriptor device_descriptor_;
  InternalState state_;
  std::unique_ptr<VideoCaptureDevice::Client> client_;

  Microsoft::WRL::ComPtr<IBaseFilter> capture_filter_;

  Microsoft::WRL::ComPtr<IGraphBuilder> graph_builder_;
  Microsoft::WRL::ComPtr<ICaptureGraphBuilder2> capture_graph_builder_;

  Microsoft::WRL::ComPtr<IMediaControl> media_control_;
  Microsoft::WRL::ComPtr<IPin> input_sink_pin_;
  Microsoft::WRL::ComPtr<IPin> output_capture_pin_;

  scoped_refptr<SinkFilter> sink_filter_;

  // Map of all capabilities this device support.
  CapabilityList capabilities_;

  VideoCaptureFormat capture_format_;

  Microsoft::WRL::ComPtr<ICameraControl> camera_control_;
  Microsoft::WRL::ComPtr<IVideoProcAmp> video_control_;
  // These flags keep the manual/auto mode between cycles of SetPhotoOptions().
  bool white_balance_mode_manual_;
  bool exposure_mode_manual_;
  bool focus_mode_manual_;

  base::TimeTicks first_ref_time_;

  base::queue<TakePhotoCallback> take_photo_callbacks_;

  base::ThreadChecker thread_checker_;

  bool enable_get_photo_state_;

  absl::optional<int> camera_rotation_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureDeviceWin);
};

}  // namespace media

#endif  // MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_WIN_H_
