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

#include <dshow.h>

#include <atomic>
#include <memory>
#include <vector>

#include "modules/video_capture/video_capture_defines.h"
#include "modules/video_capture/windows/help_functions_ds.h"
#include "rtc_base/thread_annotations.h"
#include "rtc_base/thread_checker.h"

namespace webrtc {
namespace videocapturemodule {
// forward declarations
class CaptureSinkFilter;

// Input pin for camera input
// Implements IMemInputPin, IPin.
class CaptureInputPin : public IMemInputPin, public IPin {
 public:
  CaptureInputPin(CaptureSinkFilter* filter);

  HRESULT SetRequestedCapability(const VideoCaptureCapability& capability);

  // Notifications from the filter.
  void OnFilterActivated();
  void OnFilterDeactivated();

 protected:
  virtual ~CaptureInputPin();

 private:
  CaptureSinkFilter* Filter() const;

  HRESULT AttemptConnection(IPin* receive_pin, const AM_MEDIA_TYPE* media_type);
  std::vector<AM_MEDIA_TYPE*> DetermineCandidateFormats(
      IPin* receive_pin,
      const AM_MEDIA_TYPE* media_type);
  void ClearAllocator(bool decommit);
  HRESULT CheckDirection(IPin* pin) const;

  // IUnknown
  STDMETHOD(QueryInterface)(REFIID riid, void** ppv) override;

  // clang-format off
  // clang isn't sure what to do with the longer STDMETHOD() function
  // declarations.

  // IPin
  STDMETHOD(Connect)(IPin* receive_pin,
                     const AM_MEDIA_TYPE* media_type) override;
  STDMETHOD(ReceiveConnection)(IPin* connector,
                               const AM_MEDIA_TYPE* media_type) override;
  STDMETHOD(Disconnect)() override;
  STDMETHOD(ConnectedTo)(IPin** pin) override;
  STDMETHOD(ConnectionMediaType)(AM_MEDIA_TYPE* media_type) override;
  STDMETHOD(QueryPinInfo)(PIN_INFO* info) override;
  STDMETHOD(QueryDirection)(PIN_DIRECTION* pin_dir) override;
  STDMETHOD(QueryId)(LPWSTR* id) override;
  STDMETHOD(QueryAccept)(const AM_MEDIA_TYPE* media_type) override;
  STDMETHOD(EnumMediaTypes)(IEnumMediaTypes** types) override;
  STDMETHOD(QueryInternalConnections)(IPin** pins, ULONG* count) override;
  STDMETHOD(EndOfStream)() override;
  STDMETHOD(BeginFlush)() override;
  STDMETHOD(EndFlush)() override;
  STDMETHOD(NewSegment)(REFERENCE_TIME start, REFERENCE_TIME stop,
                        double rate) override;

  // IMemInputPin
  STDMETHOD(GetAllocator)(IMemAllocator** allocator) override;
  STDMETHOD(NotifyAllocator)(IMemAllocator* allocator, BOOL read_only) override;
  STDMETHOD(GetAllocatorRequirements)(ALLOCATOR_PROPERTIES* props) override;
  STDMETHOD(Receive)(IMediaSample* sample) override;
  STDMETHOD(ReceiveMultiple)(IMediaSample** samples, long count,
                             long* processed) override;
  STDMETHOD(ReceiveCanBlock)() override;
  // clang-format on

  rtc::ThreadChecker main_checker_;
  rtc::ThreadChecker capture_checker_;

  VideoCaptureCapability requested_capability_ RTC_GUARDED_BY(main_checker_);
  // Accessed on the main thread when Filter()->IsStopped() (capture thread not
  // running), otherwise accessed on the capture thread.
  VideoCaptureCapability resulting_capability_;
  DWORD capture_thread_id_ = 0;
  rtc::scoped_refptr<IMemAllocator> allocator_ RTC_GUARDED_BY(main_checker_);
  rtc::scoped_refptr<IPin> receive_pin_ RTC_GUARDED_BY(main_checker_);
  std::atomic_bool flushing_{false};
  std::atomic_bool runtime_error_{false};
  // Holds a referenceless pointer to the owning filter, the name and
  // direction of the pin. The filter pointer can be considered const.
  PIN_INFO info_ = {};
  AM_MEDIA_TYPE media_type_ RTC_GUARDED_BY(main_checker_) = {};
};

// Implement IBaseFilter (including IPersist and IMediaFilter).
class CaptureSinkFilter : public IBaseFilter {
 public:
  CaptureSinkFilter(VideoCaptureExternal* capture_observer);

  HRESULT SetRequestedCapability(const VideoCaptureCapability& capability);

  // Called on the capture thread.
  void ProcessCapturedFrame(unsigned char* buffer,
                            size_t length,
                            const VideoCaptureCapability& frame_info);

  void NotifyEvent(long code, LONG_PTR param1, LONG_PTR param2);
  bool IsStopped() const;

  //  IUnknown
  STDMETHOD(QueryInterface)(REFIID riid, void** ppv) override;

  // IPersist
  STDMETHOD(GetClassID)(CLSID* clsid) override;

  // IMediaFilter.
  STDMETHOD(GetState)(DWORD msecs, FILTER_STATE* state) override;
  STDMETHOD(SetSyncSource)(IReferenceClock* clock) override;
  STDMETHOD(GetSyncSource)(IReferenceClock** clock) override;
  STDMETHOD(Pause)() override;
  STDMETHOD(Run)(REFERENCE_TIME start) override;
  STDMETHOD(Stop)() override;

  // IBaseFilter
  STDMETHOD(EnumPins)(IEnumPins** pins) override;
  STDMETHOD(FindPin)(LPCWSTR id, IPin** pin) override;
  STDMETHOD(QueryFilterInfo)(FILTER_INFO* info) override;
  STDMETHOD(JoinFilterGraph)(IFilterGraph* graph, LPCWSTR name) override;
  STDMETHOD(QueryVendorInfo)(LPWSTR* vendor_info) override;

 protected:
  virtual ~CaptureSinkFilter();

 private:
  rtc::ThreadChecker main_checker_;
  const rtc::scoped_refptr<ComRefCount<CaptureInputPin>> input_pin_;
  VideoCaptureExternal* const capture_observer_;
  FILTER_INFO info_ RTC_GUARDED_BY(main_checker_) = {};
  // Set/cleared in JoinFilterGraph. The filter must be stopped (no capture)
  // at that time, so no lock is required. While the state is not stopped,
  // the sink will be used from the capture thread.
  IMediaEventSink* sink_ = nullptr;
  FILTER_STATE state_ RTC_GUARDED_BY(main_checker_) = State_Stopped;
};
}  // namespace videocapturemodule
}  // namespace webrtc
#endif  // MODULES_VIDEO_CAPTURE_MAIN_SOURCE_WINDOWS_SINK_FILTER_DS_H_
