// Copyright 2018 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.

#include <mfidl.h>

#include <ks.h>
#include <ksmedia.h>
#include <mfapi.h>
#include <mferror.h>
#include <mfobjects.h>
#include <stddef.h>
#include <vidcap.h>
#include <wrl.h>
#include <wrl/client.h>

#include "base/bind.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/strings/sys_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/win/windows_version.h"
#include "media/base/media_switches.h"
#include "media/capture/video/win/video_capture_device_factory_win.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

namespace {

// MediaFoundation devices
const wchar_t* kMFDeviceId0 = L"\\\\?\\usb#vid_0000&pid_0000&mi_00";
const wchar_t* kMFDeviceName0 = L"Device 0";

const wchar_t* kMFDeviceId1 = L"\\\\?\\usb#vid_0001&pid_0001&mi_00";
const wchar_t* kMFDeviceName1 = L"Device 1";

const wchar_t* kMFDeviceId2 = L"\\\\?\\usb#vid_0002&pid_0002&mi_00";
const wchar_t* kMFDeviceName2 = L"Device 2";

const wchar_t* kMFDeviceId5 = L"\\\\?\\usb#vid_0005&pid_0005&mi_00";
const wchar_t* kMFDeviceName5 = L"Dazzle";

const wchar_t* kMFDeviceId6 = L"\\\\?\\usb#vid_eb1a&pid_2860&mi_00";
const wchar_t* kMFDeviceName6 = L"Empia Device";

// DirectShow devices
const wchar_t* kDirectShowDeviceId0 = L"\\\\?\\usb#vid_0000&pid_0000&mi_00";
const wchar_t* kDirectShowDeviceName0 = L"Device 0";

const wchar_t* kDirectShowDeviceId1 = L"\\\\?\\usb#vid_0001&pid_0001&mi_00#1";
const wchar_t* kDirectShowDeviceName1 = L"Device 1";

const wchar_t* kDirectShowDeviceId3 = L"Virtual Camera 3";
const wchar_t* kDirectShowDeviceName3 = L"Virtual Camera";

const wchar_t* kDirectShowDeviceId4 = L"Virtual Camera 4";
const wchar_t* kDirectShowDeviceName4 = L"Virtual Camera";

const wchar_t* kDirectShowDeviceId5 = L"\\\\?\\usb#vid_0005&pid_0005&mi_00#5";
const wchar_t* kDirectShowDeviceName5 = L"Dazzle";

const wchar_t* kDirectShowDeviceId6 = L"\\\\?\\usb#vid_eb1a&pid_2860&mi_00";
const wchar_t* kDirectShowDeviceName6 = L"Empia Device";

constexpr int kWidth = 1280;
constexpr int kHeight = 720;

constexpr int kFps = 30;

using iterator = std::vector<VideoCaptureDeviceInfo>::const_iterator;
iterator FindDeviceInRange(iterator begin,
                           iterator end,
                           const std::string& device_id) {
  return std::find_if(begin, end,
                      [device_id](const VideoCaptureDeviceInfo& device_info) {
                        return device_id == device_info.descriptor.device_id;
                      });
}

template <class Interface>
Interface* AddReference(Interface* object) {
  DCHECK(object);
  object->AddRef();
  return object;
}

template <class Interface>
class StubInterface
    : public base::RefCountedThreadSafe<StubInterface<Interface>>,
      public Interface {
 public:
  // IUnknown
  IFACEMETHODIMP QueryInterface(REFIID riid, void** object) override {
    if (riid == __uuidof(this) || riid == __uuidof(IUnknown)) {
      *object = AddReference(this);
      return S_OK;
    }
    return E_NOINTERFACE;
  }
  IFACEMETHODIMP_(ULONG) AddRef() override {
    base::RefCountedThreadSafe<StubInterface>::AddRef();
    return 1U;
  }
  IFACEMETHODIMP_(ULONG) Release() override {
    base::RefCountedThreadSafe<StubInterface>::Release();
    return 1U;
  }

 protected:
  friend class base::RefCountedThreadSafe<StubInterface<Interface>>;
  virtual ~StubInterface() = default;
};

template <class Interface>
class StubDeviceInterface : public StubInterface<Interface> {
 public:
  StubDeviceInterface(std::string device_id)
      : device_id_(std::move(device_id)) {}
  const std::string& device_id() const { return device_id_; }

 protected:
  ~StubDeviceInterface() override = default;

 private:
  std::string device_id_;
};

// Stub IAMCameraControl with pan, tilt and zoom ranges for all devices except
// from Device 1.
class StubAMCameraControl final : public StubDeviceInterface<IAMCameraControl> {
 public:
  using StubDeviceInterface::StubDeviceInterface;
  // IAMCameraControl
  IFACEMETHODIMP Get(long property, long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetRange(long property,
                          long* min,
                          long* max,
                          long* step,
                          long* default_value,
                          long* caps_flags) override {
    switch (property) {
      case CameraControl_Pan:
      case CameraControl_Tilt:
      case CameraControl_Zoom:
        if (device_id() != base::SysWideToUTF8(kMFDeviceId1)) {
          *min = 100;
          *max = 400;
          *step = 1;
          *default_value = 100;
          *caps_flags = CameraControl_Flags_Manual;
          return S_OK;
        }
        break;
    }
    return E_NOTIMPL;
  }
  IFACEMETHODIMP Set(long property, long value, long flags) override {
    return E_NOTIMPL;
  }

 private:
  ~StubAMCameraControl() override = default;
};

class StubAMVideoProcAmp final : public StubDeviceInterface<IAMVideoProcAmp> {
 public:
  using StubDeviceInterface::StubDeviceInterface;
  // IAMVideoProcAmp
  IFACEMETHODIMP Get(long property, long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetRange(long property,
                          long* min,
                          long* max,
                          long* step,
                          long* default_value,
                          long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP Set(long property, long value, long flags) override {
    return E_NOTIMPL;
  }

 private:
  ~StubAMVideoProcAmp() override = default;
};

class StubMFActivate final : public StubInterface<IMFActivate> {
 public:
  StubMFActivate(const std::wstring& symbolic_link,
                 const std::wstring& name,
                 bool kscategory_video_camera,
                 bool kscategory_sensor_camera)
      : symbolic_link_(symbolic_link),
        name_(name),
        kscategory_video_camera_(kscategory_video_camera),
        kscategory_sensor_camera_(kscategory_sensor_camera) {}

  bool MatchesQuery(IMFAttributes* query, HRESULT* status) {
    UINT32 count;
    *status = query->GetCount(&count);
    if (FAILED(*status))
      return false;
    GUID value;
    *status = query->GetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, &value);
    if (FAILED(*status))
      return false;
    if (value != MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID)
      return false;
    *status = query->GetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_CATEGORY,
                             &value);
    if (SUCCEEDED(*status)) {
      if ((value == KSCATEGORY_SENSOR_CAMERA && kscategory_sensor_camera_) ||
          (value == KSCATEGORY_VIDEO_CAMERA && kscategory_video_camera_))
        return true;
    } else if (*status == MF_E_ATTRIBUTENOTFOUND) {
      // When no category attribute is specified, it should behave the same as
      // if KSCATEGORY_VIDEO_CAMERA is specified.
      *status = S_OK;
      if (kscategory_video_camera_)
        return true;
    }
    return false;
  }

  // IMFAttributes
  IFACEMETHODIMP GetItem(REFGUID key, PROPVARIANT* value) override {
    return E_FAIL;
  }
  IFACEMETHODIMP GetItemType(REFGUID guidKey,
                             MF_ATTRIBUTE_TYPE* pType) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP CompareItem(REFGUID guidKey,
                             REFPROPVARIANT Value,
                             BOOL* pbResult) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP Compare(IMFAttributes* pTheirs,
                         MF_ATTRIBUTES_MATCH_TYPE MatchType,
                         BOOL* pbResult) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetUINT32(REFGUID key, UINT32* value) override {
    if (key == MF_MT_INTERLACE_MODE) {
      *value = MFVideoInterlace_Progressive;
      return S_OK;
    }
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetUINT64(REFGUID key, UINT64* value) override {
    return E_FAIL;
  }
  IFACEMETHODIMP GetDouble(REFGUID guidKey, double* pfValue) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetGUID(REFGUID key, GUID* value) override { return E_FAIL; }
  IFACEMETHODIMP GetStringLength(REFGUID guidKey, UINT32* pcchLength) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetString(REFGUID guidKey,
                           LPWSTR pwszValue,
                           UINT32 cchBufSize,
                           UINT32* pcchLength) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetAllocatedString(REFGUID guidKey,
                                    LPWSTR* ppwszValue,
                                    UINT32* pcchLength) override {
    std::wstring value;
    if (guidKey == MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK) {
      value = symbolic_link_;
    } else if (guidKey == MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME) {
      value = name_;
    } else {
      return E_NOTIMPL;
    }
    *ppwszValue = static_cast<wchar_t*>(
        CoTaskMemAlloc((value.size() + 1) * sizeof(wchar_t)));
    wcscpy(*ppwszValue, value.c_str());
    *pcchLength = value.length();
    return S_OK;
  }
  IFACEMETHODIMP GetBlobSize(REFGUID guidKey, UINT32* pcbBlobSize) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetBlob(REFGUID guidKey,
                         UINT8* pBuf,
                         UINT32 cbBufSize,
                         UINT32* pcbBlobSize) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetAllocatedBlob(REFGUID guidKey,
                                  UINT8** ppBuf,
                                  UINT32* pcbSize) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetUnknown(REFGUID guidKey,
                            REFIID riid,
                            LPVOID* ppv) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP SetItem(REFGUID guidKey, REFPROPVARIANT Value) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP DeleteItem(REFGUID guidKey) override { return E_NOTIMPL; }
  IFACEMETHODIMP DeleteAllItems(void) override { return E_NOTIMPL; }
  IFACEMETHODIMP SetUINT32(REFGUID guidKey, UINT32 unValue) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP SetUINT64(REFGUID guidKey, UINT64 unValue) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP SetDouble(REFGUID guidKey, double fValue) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP SetGUID(REFGUID guidKey, REFGUID guidValue) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP SetString(REFGUID guidKey, LPCWSTR wszValue) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP SetBlob(REFGUID guidKey,
                         const UINT8* pBuf,
                         UINT32 cbBufSize) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP SetUnknown(REFGUID guidKey, IUnknown* pUnknown) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP LockStore(void) override { return E_NOTIMPL; }
  IFACEMETHODIMP UnlockStore(void) override { return E_NOTIMPL; }
  IFACEMETHODIMP GetCount(UINT32* pcItems) override { return E_NOTIMPL; }
  IFACEMETHODIMP GetItemByIndex(UINT32 unIndex,
                                GUID* pguidKey,
                                PROPVARIANT* pValue) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP CopyAllItems(IMFAttributes* pDest) override {
    return E_NOTIMPL;
  }
  // IMFActivate
  IFACEMETHODIMP ActivateObject(REFIID riid, void** ppv) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP DetachObject(void) override { return E_NOTIMPL; }
  IFACEMETHODIMP ShutdownObject(void) override { return E_NOTIMPL; }

 private:
  ~StubMFActivate() override = default;

  const std::wstring symbolic_link_;
  const std::wstring name_;
  const bool kscategory_video_camera_;
  const bool kscategory_sensor_camera_;
};

// Stub IMFMediaSourceEx with IAMCameraControl and IAMVideoProcAmp interfaces
// for all devices except from Device 0.
class StubMFMediaSource final : public StubDeviceInterface<IMFMediaSourceEx> {
 public:
  StubMFMediaSource(std::string device_id,
                    std::vector<VideoPixelFormat> native_formats)
      : StubDeviceInterface(device_id),
        native_formats_(std::move(native_formats)) {
    // If no native formats were specified, default to I420
    if (native_formats_.size() == 0) {
      native_formats_.push_back(PIXEL_FORMAT_I420);
    }
  }

  using StubDeviceInterface::StubDeviceInterface;
  // IUnknown
  IFACEMETHODIMP QueryInterface(REFIID riid, void** object) override {
    if (device_id() != base::SysWideToUTF8(kMFDeviceId0)) {
      if (riid == __uuidof(IAMCameraControl)) {
        *object = AddReference(new StubAMCameraControl(device_id()));
        return S_OK;
      }
      if (riid == __uuidof(IAMVideoProcAmp)) {
        *object = AddReference(new StubAMVideoProcAmp(device_id()));
        return S_OK;
      }
    }
    if (riid == __uuidof(IMFMediaSource)) {
      *object = AddReference(static_cast<IMFMediaSource*>(this));
      return S_OK;
    }
    if (riid == _uuidof(IMFMediaEventGenerator)) {
      *object = AddReference(static_cast<IMFMediaEventGenerator*>(this));
      return S_OK;
    }

    return StubDeviceInterface::QueryInterface(riid, object);
  }
  // IMFMediaEventGenerator
  IFACEMETHODIMP BeginGetEvent(IMFAsyncCallback* callback,
                               IUnknown* state) override {
    return S_OK;
  }
  IFACEMETHODIMP EndGetEvent(IMFAsyncResult* result,
                             IMFMediaEvent** event) override {
    return S_OK;
  }
  IFACEMETHODIMP GetEvent(DWORD flags, IMFMediaEvent** event) override {
    return S_OK;
  }
  IFACEMETHODIMP QueueEvent(MediaEventType met,
                            REFGUID extended_type,
                            HRESULT status,
                            const PROPVARIANT* value) override {
    return S_OK;
  }
  // IMFMediaSource
  IFACEMETHODIMP CreatePresentationDescriptor(
      IMFPresentationDescriptor** presentation_descriptor) override {
    HRESULT hr = S_OK;
    std::vector<Microsoft::WRL::ComPtr<IMFMediaType>> media_types;
    std::vector<IMFMediaType*> media_type_list;
    for (const VideoPixelFormat& pixel_format : native_formats_) {
      Microsoft::WRL::ComPtr<IMFMediaType> media_type;
      hr = MFCreateMediaType(&media_type);
      if (FAILED(hr)) {
        return hr;
      }
      hr = media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
      if (FAILED(hr)) {
        return hr;
      }
      GUID subType = GUID_NULL;
      switch (pixel_format) {
        case PIXEL_FORMAT_I420:
          subType = MFVideoFormat_I420;
          break;
        case PIXEL_FORMAT_NV12:
          subType = MFVideoFormat_NV12;
          break;
        default:
          break;
      }
      hr = media_type->SetGUID(MF_MT_SUBTYPE, subType);
      if (FAILED(hr)) {
        return hr;
      }
      hr = MFSetAttributeSize(media_type.Get(), MF_MT_FRAME_SIZE, kWidth,
                              kHeight);
      if (FAILED(hr)) {
        return hr;
      }
      hr = MFSetAttributeRatio(media_type.Get(), MF_MT_FRAME_RATE, kFps, 1);
      if (FAILED(hr)) {
        return hr;
      }
      media_types.push_back(media_type);
      media_type_list.push_back(media_type.Get());
    }
    if (media_type_list.empty()) {
      ADD_FAILURE() << "media_type_list empty";
      return MF_E_UNEXPECTED;
    }
    Microsoft::WRL::ComPtr<IMFStreamDescriptor> stream_descriptor;
    hr = MFCreateStreamDescriptor(0, media_type_list.size(),
                                  &media_type_list[0], &stream_descriptor);
    if (FAILED(hr)) {
      return hr;
    }
    IMFStreamDescriptor* stream_descriptors = stream_descriptor.Get();
    return MFCreatePresentationDescriptor(1, &stream_descriptors,
                                          presentation_descriptor);
  }
  IFACEMETHODIMP GetCharacteristics(DWORD* characteristics) override {
    return S_OK;
  }
  IFACEMETHODIMP Pause() override { return S_OK; }
  IFACEMETHODIMP Shutdown() override { return S_OK; }
  IFACEMETHODIMP Start(IMFPresentationDescriptor* presentation_descriptor,
                       const GUID* time_format,
                       const PROPVARIANT* start_position) override {
    return S_OK;
  }
  IFACEMETHODIMP Stop() override { return S_OK; }
  // IMFMediaSourceEx
  IFACEMETHODIMP GetSourceAttributes(IMFAttributes** attributes) {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetStreamAttributes(DWORD stream_id,
                                     IMFAttributes** attributes) {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP SetD3DManager(IUnknown* manager) { return S_OK; }

 private:
  ~StubMFMediaSource() override = default;
  std::vector<VideoPixelFormat> native_formats_;
};

// Stub ICameraControl with pan, tilt and zoom range for all devices except
// from Device 5.
class StubCameraControl final : public StubDeviceInterface<ICameraControl> {
 public:
  using StubDeviceInterface::StubDeviceInterface;
  // ICameraControl
  IFACEMETHODIMP get_Exposure(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_ExposureRelative(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_FocalLengths(long* ocular_focal_length,
                                  long* objective_focal_length_min,
                                  long* objective_focal_length_max) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_Focus(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_FocusRelative(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_Iris(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_IrisRelative(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_Pan(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_PanRelative(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_PanTilt(long* pan_value,
                             long* tilt_value,
                             long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_PanTiltRelative(long* pan_value,
                                     long* tilt_value,
                                     long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_PrivacyMode(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_Roll(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_RollRelative(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_ScanMode(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_Tilt(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_TiltRelative(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_Zoom(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_ZoomRelative(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_Exposure(long* min,
                                   long* max,
                                   long* step,
                                   long* default_value,
                                   long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_ExposureRelative(long* min,
                                           long* max,
                                           long* step,
                                           long* default_value,
                                           long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_Focus(long* min,
                                long* max,
                                long* step,
                                long* default_value,
                                long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_FocusRelative(long* min,
                                        long* max,
                                        long* step,
                                        long* default_value,
                                        long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_Iris(long* min,
                               long* max,
                               long* step,
                               long* default_value,
                               long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_IrisRelative(long* min,
                                       long* max,
                                       long* step,
                                       long* default_value,
                                       long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_Pan(long* min,
                              long* max,
                              long* step,
                              long* default_value,
                              long* caps_flags) override {
    if (device_id() != base::SysWideToUTF8(kDirectShowDeviceId5)) {
      *min = 100;
      *max = 400;
      *step = 1;
      *default_value = 100;
      *caps_flags = CameraControl_Flags_Manual;
      return S_OK;
    }
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_PanRelative(long* min,
                                      long* max,
                                      long* step,
                                      long* default_value,
                                      long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_Roll(long* min,
                               long* max,
                               long* step,
                               long* default_value,
                               long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_RollRelative(long* min,
                                       long* max,
                                       long* step,
                                       long* default_value,
                                       long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_Tilt(long* min,
                               long* max,
                               long* step,
                               long* default_value,
                               long* caps_flags) override {
    if (device_id() != base::SysWideToUTF8(kDirectShowDeviceId5)) {
      *min = 100;
      *max = 400;
      *step = 1;
      *default_value = 100;
      *caps_flags = CameraControl_Flags_Manual;
      return S_OK;
    }
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_TiltRelative(long* min,
                                       long* max,
                                       long* step,
                                       long* default_value,
                                       long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_Zoom(long* min,
                               long* max,
                               long* step,
                               long* default_value,
                               long* caps_flags) override {
    if (device_id() != base::SysWideToUTF8(kDirectShowDeviceId5)) {
      *min = 100;
      *max = 400;
      *step = 1;
      *default_value = 100;
      *caps_flags = CameraControl_Flags_Manual;
      return S_OK;
    }
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_ZoomRelative(long* min,
                                       long* max,
                                       long* step,
                                       long* default_value,
                                       long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_Exposure(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_ExposureRelative(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_Focus(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_FocusRelative(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_Iris(long value, long flags) override { return E_NOTIMPL; }
  IFACEMETHODIMP put_IrisRelative(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_Pan(long value, long flags) override { return E_NOTIMPL; }
  IFACEMETHODIMP put_PanRelative(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_PanTilt(long pan_value,
                             long tilt_value,
                             long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_PanTiltRelative(long pan_value,
                                     long tilt_value,
                                     long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_PrivacyMode(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_Roll(long value, long flags) override { return E_NOTIMPL; }
  IFACEMETHODIMP put_RollRelative(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_ScanMode(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_Tilt(long value, long flags) override { return E_NOTIMPL; }
  IFACEMETHODIMP put_TiltRelative(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_Zoom(long value, long flags) override { return E_NOTIMPL; }
  IFACEMETHODIMP put_ZoomRelative(long value, long flags) override {
    return E_NOTIMPL;
  }

 private:
  ~StubCameraControl() override = default;
};

class StubVideoProcAmp final : public StubDeviceInterface<IVideoProcAmp> {
 public:
  using StubDeviceInterface::StubDeviceInterface;
  // IVideoProcAmp
  IFACEMETHODIMP get_BacklightCompensation(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_Brightness(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_ColorEnable(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_Contrast(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_DigitalMultiplier(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_Gain(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_Gamma(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_Hue(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_PowerlineFrequency(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_Saturation(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_Sharpness(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_WhiteBalance(long* value, long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_WhiteBalanceComponent(long* value1,
                                           long* value2,
                                           long* flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_BacklightCompensation(long* min,
                                                long* max,
                                                long* step,
                                                long* default_value,
                                                long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_Brightness(long* min,
                                     long* max,
                                     long* step,
                                     long* default_value,
                                     long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_ColorEnable(long* min,
                                      long* max,
                                      long* step,
                                      long* default_value,
                                      long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_Contrast(long* min,
                                   long* max,
                                   long* step,
                                   long* default_value,
                                   long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_DigitalMultiplier(long* min,
                                            long* max,
                                            long* step,
                                            long* default_value,
                                            long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_Gain(long* min,
                               long* max,
                               long* step,
                               long* default_value,
                               long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_Gamma(long* min,
                                long* max,
                                long* step,
                                long* default_value,
                                long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_Hue(long* min,
                              long* max,
                              long* step,
                              long* default_value,
                              long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_PowerlineFrequency(long* min,
                                             long* max,
                                             long* step,
                                             long* default_value,
                                             long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_Saturation(long* min,
                                     long* max,
                                     long* step,
                                     long* default_value,
                                     long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_Sharpness(long* min,
                                    long* max,
                                    long* step,
                                    long* default_value,
                                    long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_WhiteBalance(long* min,
                                       long* max,
                                       long* step,
                                       long* default_value,
                                       long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP getRange_WhiteBalanceComponent(long* min,
                                                long* max,
                                                long* step,
                                                long* default_value,
                                                long* caps_flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_BacklightCompensation(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_Brightness(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_ColorEnable(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_Contrast(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_DigitalMultiplier(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_Gain(long value, long flags) override { return E_NOTIMPL; }
  IFACEMETHODIMP put_Gamma(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_Hue(long value, long flags) override { return E_NOTIMPL; }
  IFACEMETHODIMP put_PowerlineFrequency(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_Saturation(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_Sharpness(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_WhiteBalance(long value, long flags) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP put_WhiteBalanceComponent(long value1,
                                           long value2,
                                           long flags) override {
    return E_NOTIMPL;
  }

 private:
  ~StubVideoProcAmp() override = default;
};

// Stub IKsTopologyInfo with 2 nodes.
// For all devices except from Device 3, the first node is
// a KSNODETYPE_VIDEO_CAMERA_TERMINAL (ICameraControl) node.
// For all devices except from Device 4, the second node is
// a KSNODETYPE_VIDEO_PROCESSING (IVideoProcAmp) node.
class StubKsTopologyInfo final : public StubDeviceInterface<IKsTopologyInfo> {
 public:
  enum { kNumNodes = 2 };
  using StubDeviceInterface::StubDeviceInterface;
  // IKsTopologyInfo
  IFACEMETHODIMP CreateNodeInstance(DWORD node_id,
                                    REFIID iid,
                                    void** object) override {
    GUID node_type;
    HRESULT hr = get_NodeType(node_id, &node_type);
    if (FAILED(hr))
      return hr;
    if (node_type == KSNODETYPE_VIDEO_CAMERA_TERMINAL) {
      EXPECT_EQ(iid, __uuidof(ICameraControl));
      *object = AddReference(new StubCameraControl(device_id()));
      return S_OK;
    }
    if (node_type == KSNODETYPE_VIDEO_PROCESSING) {
      EXPECT_EQ(iid, __uuidof(IVideoProcAmp));
      *object = AddReference(new StubVideoProcAmp(device_id()));
      return S_OK;
    }
    NOTREACHED();
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_Category(DWORD index, GUID* category) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_ConnectionInfo(
      DWORD index,
      KSTOPOLOGY_CONNECTION* connection_info) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_NodeName(DWORD node_id,
                              WCHAR* node_name,
                              DWORD buf_size,
                              DWORD* name_len) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_NodeType(DWORD node_id, GUID* node_type) override {
    EXPECT_LT(node_id, kNumNodes);
    switch (node_id) {
      case 0:
        *node_type = device_id() != base::SysWideToUTF8(kDirectShowDeviceId3)
                         ? KSNODETYPE_VIDEO_CAMERA_TERMINAL
                         : KSNODETYPE_DEV_SPECIFIC;
        return S_OK;
      case 1:
        *node_type = device_id() != base::SysWideToUTF8(kDirectShowDeviceId4)
                         ? KSNODETYPE_VIDEO_PROCESSING
                         : KSNODETYPE_DEV_SPECIFIC;
        return S_OK;
    }
    NOTREACHED();
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_NumCategories(DWORD* num_categories) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_NumConnections(DWORD* num_connections) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP get_NumNodes(DWORD* num_nodes) override {
    *num_nodes = kNumNodes;
    return S_OK;
  }

 private:
  ~StubKsTopologyInfo() override = default;
};

// Stub IBaseFilter with IKsTopologyInfo interface.
class StubBaseFilter final : public StubDeviceInterface<IBaseFilter> {
 public:
  using StubDeviceInterface::StubDeviceInterface;
  // IUnknown
  IFACEMETHODIMP QueryInterface(REFIID riid, void** object) override {
    if (riid == __uuidof(IKsTopologyInfo)) {
      *object = AddReference(new StubKsTopologyInfo(device_id()));
      return S_OK;
    }
    return StubDeviceInterface::QueryInterface(riid, object);
  }
  // IPersist
  IFACEMETHODIMP GetClassID(CLSID* class_id) override { return E_NOTIMPL; }
  // IMediaFilter
  IFACEMETHODIMP GetState(DWORD milli_secs_timeout,
                          FILTER_STATE* State) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetSyncSource(IReferenceClock** clock) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP Pause() override { return E_NOTIMPL; }
  IFACEMETHODIMP Run(REFERENCE_TIME start) override { return E_NOTIMPL; }
  IFACEMETHODIMP SetSyncSource(IReferenceClock* clock) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP Stop() override { return E_NOTIMPL; }
  // IBaseFilter
  IFACEMETHODIMP EnumPins(IEnumPins** enum_pins) override { return E_NOTIMPL; }
  IFACEMETHODIMP FindPin(LPCWSTR id, IPin** pin) override { return E_NOTIMPL; }
  IFACEMETHODIMP JoinFilterGraph(IFilterGraph* graph, LPCWSTR name) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP QueryFilterInfo(FILTER_INFO* info) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP QueryVendorInfo(LPWSTR* vendor_info) override {
    return E_NOTIMPL;
  }

 private:
  ~StubBaseFilter() override = default;
};

class StubPropertyBag final : public StubInterface<IPropertyBag> {
 public:
  StubPropertyBag(const wchar_t* device_path, const wchar_t* description)
      : device_path_(device_path), description_(description) {}

  IFACEMETHODIMP Read(LPCOLESTR pszPropName,
                      VARIANT* pVar,
                      IErrorLog* pErrorLog) override {
    if (pszPropName == std::wstring(L"Description")) {
      pVar->vt = VT_BSTR;
      pVar->bstrVal = SysAllocString(description_);
      return S_OK;
    }
    if (pszPropName == std::wstring(L"DevicePath")) {
      pVar->vt = VT_BSTR;
      pVar->bstrVal = SysAllocString(device_path_);
      return S_OK;
    }
    return E_NOTIMPL;
  }
  IFACEMETHODIMP Write(LPCOLESTR pszPropName, VARIANT* pVar) override {
    return E_NOTIMPL;
  }

 private:
  ~StubPropertyBag() override = default;

  const wchar_t* device_path_;
  const wchar_t* description_;
};

class StubMoniker final : public StubInterface<IMoniker> {
 public:
  StubMoniker(const wchar_t* device_path, const wchar_t* description)
      : device_path_(device_path), description_(description) {}

  IFACEMETHODIMP GetClassID(CLSID* pClassID) override { return E_NOTIMPL; }
  IFACEMETHODIMP IsDirty(void) override { return E_NOTIMPL; }
  IFACEMETHODIMP Load(IStream* pStm) override { return E_NOTIMPL; }
  IFACEMETHODIMP Save(IStream* pStm, BOOL fClearDirty) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetSizeMax(ULARGE_INTEGER* pcbSize) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP BindToObject(IBindCtx* pbc,
                              IMoniker* pmkToLeft,
                              REFIID riidResult,
                              void** ppvResult) override {
    if (riidResult == __uuidof(IBaseFilter)) {
      *ppvResult =
          AddReference(new StubBaseFilter(base::SysWideToUTF8(device_path_)));
      return S_OK;
    }
    return MK_E_NOOBJECT;
  }
  IFACEMETHODIMP BindToStorage(IBindCtx* pbc,
                               IMoniker* pmkToLeft,
                               REFIID riid,
                               void** ppvObj) override {
    *ppvObj = AddReference(new StubPropertyBag(device_path_, description_));
    return S_OK;
  }
  IFACEMETHODIMP Reduce(IBindCtx* pbc,
                        DWORD dwReduceHowFar,
                        IMoniker** ppmkToLeft,
                        IMoniker** ppmkReduced) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP ComposeWith(IMoniker* pmkRight,
                             BOOL fOnlyIfNotGeneric,
                             IMoniker** ppmkComposite) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP Enum(BOOL fForward, IEnumMoniker** ppenumMoniker) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP IsEqual(IMoniker* pmkOtherMoniker) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP Hash(DWORD* pdwHash) override { return E_NOTIMPL; }
  IFACEMETHODIMP IsRunning(IBindCtx* pbc,
                           IMoniker* pmkToLeft,
                           IMoniker* pmkNewlyRunning) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetTimeOfLastChange(IBindCtx* pbc,
                                     IMoniker* pmkToLeft,
                                     FILETIME* pFileTime) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP Inverse(IMoniker** ppmk) override { return E_NOTIMPL; }
  IFACEMETHODIMP CommonPrefixWith(IMoniker* pmkOther,
                                  IMoniker** ppmkPrefix) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP RelativePathTo(IMoniker* pmkOther,
                                IMoniker** ppmkRelPath) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP GetDisplayName(IBindCtx* pbc,
                                IMoniker* pmkToLeft,
                                LPOLESTR* ppszDisplayName) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP ParseDisplayName(IBindCtx* pbc,
                                  IMoniker* pmkToLeft,
                                  LPOLESTR pszDisplayName,
                                  ULONG* pchEaten,
                                  IMoniker** ppmkOut) override {
    return E_NOTIMPL;
  }
  IFACEMETHODIMP IsSystemMoniker(DWORD* pdwMksys) override { return E_NOTIMPL; }

 private:
  ~StubMoniker() override = default;

  const wchar_t* device_path_;
  const wchar_t* description_;
};

class StubEnumMoniker : public StubInterface<IEnumMoniker> {
 public:
  StubEnumMoniker(std::vector<scoped_refptr<StubMoniker>> monikers)
      : monikers_(std::move(monikers)) {}

  IFACEMETHODIMP Next(ULONG celt,
                      IMoniker** rgelt,
                      ULONG* celt_fetched) override {
    if (cursor_position_ >= monikers_.size())
      return S_FALSE;
    const ULONG original_cursor_position = cursor_position_;
    while (celt-- > 0 && cursor_position_ < monikers_.size())
      *rgelt++ = AddReference(monikers_[cursor_position_++].get());
    if (celt_fetched)
      *celt_fetched = cursor_position_ - original_cursor_position;
    return S_OK;
  }
  IFACEMETHODIMP Skip(ULONG celt) override { return E_NOTIMPL; }
  IFACEMETHODIMP Reset(void) override { return E_NOTIMPL; }
  IFACEMETHODIMP Clone(IEnumMoniker** enum_moniker) override {
    return E_NOTIMPL;
  }

 private:
  ~StubEnumMoniker() override = default;

  std::vector<scoped_refptr<StubMoniker>> monikers_;
  ULONG cursor_position_ = 0;
};

class FakeVideoCaptureDeviceFactoryWin : public VideoCaptureDeviceFactoryWin {
 public:
  void set_disable_get_supported_formats_mf_mocking(
      bool disable_get_supported_formats_mf_mocking) {
    disable_get_supported_formats_mf_mocking_ =
        disable_get_supported_formats_mf_mocking;
  }

  void AddNativeFormatForMfDevice(std::wstring device_id,
                                  VideoPixelFormat format) {
    device_source_native_formats_[device_id].push_back(format);
  }

 protected:
  bool CreateDeviceEnumMonikerDirectShow(IEnumMoniker** enum_moniker) override {
    *enum_moniker = AddReference(new StubEnumMoniker(
        {base::MakeRefCounted<StubMoniker>(kDirectShowDeviceId0,
                                           kDirectShowDeviceName0),
         base::MakeRefCounted<StubMoniker>(kDirectShowDeviceId1,
                                           kDirectShowDeviceName1),
         base::MakeRefCounted<StubMoniker>(kDirectShowDeviceId3,
                                           kDirectShowDeviceName3),
         base::MakeRefCounted<StubMoniker>(kDirectShowDeviceId4,
                                           kDirectShowDeviceName4),
         base::MakeRefCounted<StubMoniker>(kDirectShowDeviceId5,
                                           kDirectShowDeviceName5),
         base::MakeRefCounted<StubMoniker>(kDirectShowDeviceId6,
                                           kDirectShowDeviceName6)}));
    return true;
  }
  bool CreateDeviceSourceMediaFoundation(
      Microsoft::WRL::ComPtr<IMFAttributes> attributes,
      IMFMediaSource** source) override {
    UINT32 length;
    if (FAILED(attributes->GetStringLength(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
            &length))) {
      return false;
    }
    std::wstring symbolic_link(length, wchar_t());
    if (FAILED(attributes->GetString(
            MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
            &symbolic_link[0], length + 1, &length))) {
      return false;
    }
    const bool has_dxgi_device_manager =
        static_cast<bool>(dxgi_device_manager_for_testing());
    if (use_d3d11_with_media_foundation_for_testing() !=
        has_dxgi_device_manager) {
      return false;
    }
    *source = AddReference(
        new StubMFMediaSource(base::SysWideToUTF8(symbolic_link),
                              device_source_native_formats_[symbolic_link]));
    return true;
  }
  bool EnumerateDeviceSourcesMediaFoundation(
      Microsoft::WRL::ComPtr<IMFAttributes> attributes,
      IMFActivate*** devices,
      UINT32* count) override {
    std::vector<scoped_refptr<StubMFActivate>> stub_devices = {
        base::MakeRefCounted<StubMFActivate>(kMFDeviceId0, kMFDeviceName0, true,
                                             false),
        base::MakeRefCounted<StubMFActivate>(kMFDeviceId1, kMFDeviceName1, true,
                                             true),
        base::MakeRefCounted<StubMFActivate>(kMFDeviceId2, kMFDeviceName2,
                                             false, true),
        base::MakeRefCounted<StubMFActivate>(kMFDeviceId5, kMFDeviceName5, true,
                                             false),
        base::MakeRefCounted<StubMFActivate>(kMFDeviceId6, kMFDeviceName6, true,
                                             false)};
    // Iterate once to get the match count and check for errors.
    *count = 0U;
    HRESULT hr;
    for (auto& device : stub_devices) {
      if (device->MatchesQuery(attributes.Get(), &hr))
        (*count)++;
      if (FAILED(hr))
        return false;
    }
    // Second iteration packs the returned devices and increments their
    // reference count.
    *devices = static_cast<IMFActivate**>(
        CoTaskMemAlloc(sizeof(IMFActivate*) * (*count)));
    int offset = 0;
    for (auto& device : stub_devices) {
      if (!device->MatchesQuery(attributes.Get(), &hr))
        continue;
      *(*devices + offset++) = AddReference(device.get());
    }
    return true;
  }

  VideoCaptureFormats GetSupportedFormatsDirectShow(
      Microsoft::WRL::ComPtr<IBaseFilter> capture_filter,
      const std::string& display_name) override {
    VideoCaptureFormats supported_formats;
    if (display_name == base::SysWideToUTF8(kDirectShowDeviceName5)) {
      VideoCaptureFormat arbitrary_format;
      supported_formats.emplace_back(arbitrary_format);
    }
    return supported_formats;
  }

  VideoCaptureFormats GetSupportedFormatsMediaFoundation(
      Microsoft::WRL::ComPtr<IMFMediaSource> source,
      const std::string& display_name) override {
    if (disable_get_supported_formats_mf_mocking_) {
      return VideoCaptureDeviceFactoryWin::GetSupportedFormatsMediaFoundation(
          source, display_name);
    }
    VideoCaptureFormats supported_formats;
    if (display_name == base::SysWideToUTF8(kMFDeviceName6)) {
      VideoCaptureFormat arbitrary_format;
      supported_formats.emplace_back(arbitrary_format);
    }
    return supported_formats;
  }

  bool disable_get_supported_formats_mf_mocking_ = false;
  std::map<std::wstring, std::vector<VideoPixelFormat>>
      device_source_native_formats_;
};

}  // namespace

class VideoCaptureDeviceFactoryWinTest : public ::testing::Test {
 protected:
  VideoCaptureDeviceFactoryWinTest()
      : media_foundation_supported_(
            VideoCaptureDeviceFactoryWin::PlatformSupportsMediaFoundation()) {}

  bool ShouldSkipMFTest() {
    if (media_foundation_supported_)
      return false;
    DVLOG(1) << "Media foundation is not supported by the current platform. "
                "Skipping test.";
    return true;
  }

  bool ShouldSkipD3D11Test() {
    // D3D11 is only supported with Media Foundation on Windows 8 or later
    if (base::win::GetVersion() >= base::win::Version::WIN8)
      return false;
    DVLOG(1) << "D3D11 with Media foundation is not supported by the current "
                "platform. "
                "Skipping test.";
    return true;
  }

  base::test::TaskEnvironment task_environment_;
  FakeVideoCaptureDeviceFactoryWin factory_;
  const bool media_foundation_supported_;
};

class VideoCaptureDeviceFactoryMFWinTest
    : public VideoCaptureDeviceFactoryWinTest,
      public testing::WithParamInterface<bool> {
  void SetUp() override {
    VideoCaptureDeviceFactoryWinTest::SetUp();
    factory_.set_use_media_foundation_for_testing(true);
  }
};

TEST_P(VideoCaptureDeviceFactoryMFWinTest, GetDevicesInfo) {
  if (ShouldSkipMFTest())
    return;

  const bool use_d3d11 = GetParam();
  if (use_d3d11 && ShouldSkipD3D11Test())
    return;
  factory_.set_use_d3d11_with_media_foundation_for_testing(use_d3d11);

  std::vector<VideoCaptureDeviceInfo> devices_info;
  base::RunLoop run_loop;
  factory_.GetDevicesInfo(base::BindLambdaForTesting(
      [&devices_info, &run_loop](std::vector<VideoCaptureDeviceInfo> result) {
        devices_info = std::move(result);
        run_loop.Quit();
      }));
  run_loop.Run();

  EXPECT_EQ(devices_info.size(), 6U);
  for (auto it = devices_info.begin(); it != devices_info.end(); it++) {
    // Verify that there are no duplicates.
    EXPECT_EQ(
        FindDeviceInRange(devices_info.begin(), it, it->descriptor.device_id),
        it);
  }
  iterator it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                                  base::SysWideToUTF8(kMFDeviceId0));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.capture_api, VideoCaptureApi::WIN_MEDIA_FOUNDATION);
  EXPECT_EQ(it->descriptor.display_name(), base::SysWideToUTF8(kMFDeviceName0));
  // No IAMCameraControl and no IAMVideoProcAmp interfaces.
  EXPECT_FALSE(it->descriptor.control_support().pan);
  EXPECT_FALSE(it->descriptor.control_support().tilt);
  EXPECT_FALSE(it->descriptor.control_support().zoom);

  it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                         base::SysWideToUTF8(kMFDeviceId1));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.capture_api, VideoCaptureApi::WIN_MEDIA_FOUNDATION);
  EXPECT_EQ(it->descriptor.display_name(), base::SysWideToUTF8(kMFDeviceName1));
  // No pan/tilt/zoom in IAMCameraControl interface.
  EXPECT_FALSE(it->descriptor.control_support().pan);
  EXPECT_FALSE(it->descriptor.control_support().tilt);
  EXPECT_FALSE(it->descriptor.control_support().zoom);

  it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                         base::SysWideToUTF8(kDirectShowDeviceId3));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.capture_api, VideoCaptureApi::WIN_DIRECT_SHOW);
  EXPECT_EQ(it->descriptor.display_name(),
            base::SysWideToUTF8(kDirectShowDeviceName3));
  // No ICameraControl interface.
  EXPECT_FALSE(it->descriptor.control_support().pan);
  EXPECT_FALSE(it->descriptor.control_support().tilt);
  EXPECT_FALSE(it->descriptor.control_support().zoom);

  it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                         base::SysWideToUTF8(kDirectShowDeviceId4));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.capture_api, VideoCaptureApi::WIN_DIRECT_SHOW);
  EXPECT_EQ(it->descriptor.display_name(),
            base::SysWideToUTF8(kDirectShowDeviceName4));
  // No IVideoProcAmp interface.
  EXPECT_FALSE(it->descriptor.control_support().pan);
  EXPECT_FALSE(it->descriptor.control_support().tilt);
  EXPECT_FALSE(it->descriptor.control_support().zoom);

  // Devices that are listed in MediaFoundation but only report supported
  // formats in DirectShow are expected to get enumerated with
  // VideoCaptureApi::WIN_DIRECT_SHOW
  it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                         base::SysWideToUTF8(kDirectShowDeviceId5));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.capture_api, VideoCaptureApi::WIN_DIRECT_SHOW);
  EXPECT_EQ(it->descriptor.display_name(),
            base::SysWideToUTF8(kDirectShowDeviceName5));
  // No pan, tilt, or zoom ranges in ICameraControl interface.
  EXPECT_FALSE(it->descriptor.control_support().pan);
  EXPECT_FALSE(it->descriptor.control_support().tilt);
  EXPECT_FALSE(it->descriptor.control_support().zoom);

  // Devices that are listed in both MediaFoundation and DirectShow but are
  // blocked for use with MediaFoundation are expected to get enumerated with
  // VideoCaptureApi::WIN_DIRECT_SHOW.
  it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                         base::SysWideToUTF8(kDirectShowDeviceId6));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.capture_api, VideoCaptureApi::WIN_DIRECT_SHOW);
  EXPECT_EQ(it->descriptor.display_name(),
            base::SysWideToUTF8(kDirectShowDeviceName6));
  EXPECT_TRUE(it->descriptor.control_support().pan);
  EXPECT_TRUE(it->descriptor.control_support().tilt);
  EXPECT_TRUE(it->descriptor.control_support().zoom);
}

TEST_P(VideoCaptureDeviceFactoryMFWinTest, GetDevicesInfo_IncludeIRCameras) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(kIncludeIRCamerasInDeviceEnumeration);

  if (ShouldSkipMFTest())
    return;

  const bool use_d3d11 = GetParam();
  if (use_d3d11 && ShouldSkipD3D11Test())
    return;
  factory_.set_use_d3d11_with_media_foundation_for_testing(use_d3d11);

  std::vector<VideoCaptureDeviceInfo> devices_info;
  base::RunLoop run_loop;
  factory_.GetDevicesInfo(base::BindLambdaForTesting(
      [&devices_info, &run_loop](std::vector<VideoCaptureDeviceInfo> result) {
        devices_info = std::move(result);
        run_loop.Quit();
      }));
  run_loop.Run();

  EXPECT_EQ(devices_info.size(), 7U);
  for (auto it = devices_info.begin(); it != devices_info.end(); it++) {
    // Verify that there are no duplicates.
    EXPECT_EQ(
        FindDeviceInRange(devices_info.begin(), it, it->descriptor.device_id),
        it);
  }
  iterator it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                                  base::SysWideToUTF8(kMFDeviceId0));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.capture_api, VideoCaptureApi::WIN_MEDIA_FOUNDATION);
  EXPECT_EQ(it->descriptor.display_name(), base::SysWideToUTF8(kMFDeviceName0));
  // No IAMCameraControl and no IAMVideoProcAmp interfaces.
  EXPECT_FALSE(it->descriptor.control_support().pan);
  EXPECT_FALSE(it->descriptor.control_support().tilt);
  EXPECT_FALSE(it->descriptor.control_support().zoom);

  it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                         base::SysWideToUTF8(kMFDeviceId1));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.capture_api, VideoCaptureApi::WIN_MEDIA_FOUNDATION);
  EXPECT_EQ(it->descriptor.display_name(), base::SysWideToUTF8(kMFDeviceName1));
  // No pan/tilt/zoom in IAMCameraControl interface.
  EXPECT_FALSE(it->descriptor.control_support().pan);
  EXPECT_FALSE(it->descriptor.control_support().tilt);
  EXPECT_FALSE(it->descriptor.control_support().zoom);

  it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                         base::SysWideToUTF8(kMFDeviceId2));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.capture_api,
            VideoCaptureApi::WIN_MEDIA_FOUNDATION_SENSOR);
  EXPECT_EQ(it->descriptor.display_name(), base::SysWideToUTF8(kMFDeviceName2));
  EXPECT_TRUE(it->descriptor.control_support().pan);
  EXPECT_TRUE(it->descriptor.control_support().tilt);
  EXPECT_TRUE(it->descriptor.control_support().zoom);

  it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                         base::SysWideToUTF8(kDirectShowDeviceId3));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.capture_api, VideoCaptureApi::WIN_DIRECT_SHOW);
  EXPECT_EQ(it->descriptor.display_name(),
            base::SysWideToUTF8(kDirectShowDeviceName3));
  // No ICameraControl interface.
  EXPECT_FALSE(it->descriptor.control_support().pan);
  EXPECT_FALSE(it->descriptor.control_support().tilt);
  EXPECT_FALSE(it->descriptor.control_support().zoom);

  it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                         base::SysWideToUTF8(kDirectShowDeviceId4));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.capture_api, VideoCaptureApi::WIN_DIRECT_SHOW);
  EXPECT_EQ(it->descriptor.display_name(),
            base::SysWideToUTF8(kDirectShowDeviceName4));
  // No IVideoProcAmp interface.
  EXPECT_FALSE(it->descriptor.control_support().pan);
  EXPECT_FALSE(it->descriptor.control_support().tilt);
  EXPECT_FALSE(it->descriptor.control_support().zoom);

  // Devices that are listed in MediaFoundation but only report supported
  // formats in DirectShow are expected to get enumerated with
  // VideoCaptureApi::WIN_DIRECT_SHOW
  it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                         base::SysWideToUTF8(kDirectShowDeviceId5));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.capture_api, VideoCaptureApi::WIN_DIRECT_SHOW);
  EXPECT_EQ(it->descriptor.display_name(),
            base::SysWideToUTF8(kDirectShowDeviceName5));
  // No pan, tilt, or zoom ranges in ICameraControl interface.
  EXPECT_FALSE(it->descriptor.control_support().pan);
  EXPECT_FALSE(it->descriptor.control_support().tilt);
  EXPECT_FALSE(it->descriptor.control_support().zoom);

  // Devices that are listed in both MediaFoundation and DirectShow but are
  // blocked for use with MediaFoundation are expected to get enumerated with
  // VideoCaptureApi::WIN_DIRECT_SHOW.
  it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                         base::SysWideToUTF8(kDirectShowDeviceId6));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.capture_api, VideoCaptureApi::WIN_DIRECT_SHOW);
  EXPECT_EQ(it->descriptor.display_name(),
            base::SysWideToUTF8(kDirectShowDeviceName6));
  EXPECT_TRUE(it->descriptor.control_support().pan);
  EXPECT_TRUE(it->descriptor.control_support().tilt);
  EXPECT_TRUE(it->descriptor.control_support().zoom);
}

TEST_P(VideoCaptureDeviceFactoryMFWinTest,
       DeviceSupportedFormatNV12Passthrough) {
  if (ShouldSkipMFTest())
    return;

  if (ShouldSkipD3D11Test())
    return;

  // Test whether the VideoCaptureDeviceFactory passes through NV12 as the
  // output pixel format when D3D11 support is enabled

  const bool use_d3d11 = GetParam();
  factory_.set_use_d3d11_with_media_foundation_for_testing(use_d3d11);
  factory_.set_disable_get_supported_formats_mf_mocking(true);

  // Specify native NV12 format for first device and I420 for others
  factory_.AddNativeFormatForMfDevice(kMFDeviceId0, PIXEL_FORMAT_NV12);
  factory_.AddNativeFormatForMfDevice(kMFDeviceId1, PIXEL_FORMAT_I420);

  const VideoPixelFormat expected_pixel_format_for_nv12 =
      use_d3d11 ? PIXEL_FORMAT_NV12 : PIXEL_FORMAT_I420;

  std::vector<VideoCaptureDeviceInfo> devices_info;
  base::RunLoop run_loop;
  factory_.GetDevicesInfo(base::BindLambdaForTesting(
      [&devices_info, &run_loop](std::vector<VideoCaptureDeviceInfo> result) {
        devices_info = std::move(result);
        run_loop.Quit();
      }));
  run_loop.Run();

  // Verify that the pixel formats advertised in supported_formats for each
  // device match the expected format (NV12 when D3D11 support is enabled and
  // the native source type for the device is NV12 or I420 in all other cases)

  iterator it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                                  base::SysWideToUTF8(kMFDeviceId0));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.display_name(), base::SysWideToUTF8(kMFDeviceName0));
  EXPECT_FALSE(it->supported_formats.empty());
  for (size_t i = 0; i < it->supported_formats.size(); i++) {
    SCOPED_TRACE(i);
    EXPECT_EQ(it->supported_formats[i].pixel_format,
              expected_pixel_format_for_nv12);
  }

  it = FindDeviceInRange(devices_info.begin(), devices_info.end(),
                         base::SysWideToUTF8(kMFDeviceId1));
  ASSERT_NE(it, devices_info.end());
  EXPECT_EQ(it->descriptor.display_name(), base::SysWideToUTF8(kMFDeviceName1));
  EXPECT_FALSE(it->supported_formats.empty());
  for (size_t i = 0; i < it->supported_formats.size(); i++) {
    SCOPED_TRACE(i);
    EXPECT_EQ(it->supported_formats[i].pixel_format,
              expected_pixel_format_for_nv12);
  }
}

INSTANTIATE_TEST_SUITE_P(VideoCaptureDeviceFactoryMFWinTests,
                         VideoCaptureDeviceFactoryMFWinTest,
                         testing::Bool());

}  // namespace media
