1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Implementation of a VideoCaptureDeviceFactory class for Windows platforms.
6 
7 #ifndef MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_FACTORY_WIN_H_
8 #define MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_FACTORY_WIN_H_
9 
10 #include <mfidl.h>
11 #include <windows.devices.enumeration.h>
12 
13 #include "base/macros.h"
14 #include "base/threading/thread.h"
15 #include "media/base/win/mf_initializer.h"
16 #include "media/capture/video/video_capture_device_factory.h"
17 
18 namespace media {
19 
20 using ABI::Windows::Foundation::IAsyncOperation;
21 using ABI::Windows::Devices::Enumeration::DeviceInformationCollection;
22 
23 // Extension of VideoCaptureDeviceFactory to create and manipulate Windows
24 // devices, via either DirectShow or MediaFoundation APIs.
25 class CAPTURE_EXPORT VideoCaptureDeviceFactoryWin
26     : public VideoCaptureDeviceFactory {
27  public:
28   static bool PlatformSupportsMediaFoundation();
29 
30   VideoCaptureDeviceFactoryWin();
31   ~VideoCaptureDeviceFactoryWin() override;
32 
33   using MFEnumDeviceSourcesFunc = decltype(&MFEnumDeviceSources);
34   using DirectShowEnumDevicesFunc =
35       base::RepeatingCallback<HRESULT(IEnumMoniker**)>;
36   using GetSupportedFormatsFunc =
37       base::RepeatingCallback<void(const VideoCaptureDeviceDescriptor&,
38                                    VideoCaptureFormats*)>;
39 
40   std::unique_ptr<VideoCaptureDevice> CreateDevice(
41       const VideoCaptureDeviceDescriptor& device_descriptor) override;
42   void GetDeviceDescriptors(
43       VideoCaptureDeviceDescriptors* device_descriptors) override;
44   void GetSupportedFormats(
45       const VideoCaptureDeviceDescriptor& device_descriptor,
46       VideoCaptureFormats* supported_formats) override;
47   void GetCameraLocationsAsync(
48       std::unique_ptr<VideoCaptureDeviceDescriptors> device_descriptors,
49       DeviceDescriptorsCallback result_callback) override;
50 
set_use_media_foundation_for_testing(bool use)51   void set_use_media_foundation_for_testing(bool use) {
52     use_media_foundation_ = use;
53   }
set_mf_enum_device_sources_func_for_testing(MFEnumDeviceSourcesFunc func)54   void set_mf_enum_device_sources_func_for_testing(
55       MFEnumDeviceSourcesFunc func) {
56     mf_enum_device_sources_func_ = func;
57   }
set_direct_show_enum_devices_func_for_testing(DirectShowEnumDevicesFunc func)58   void set_direct_show_enum_devices_func_for_testing(
59       DirectShowEnumDevicesFunc func) {
60     direct_show_enum_devices_func_ = func;
61   }
set_mf_get_supported_formats_func_for_testing(GetSupportedFormatsFunc func)62   void set_mf_get_supported_formats_func_for_testing(
63       GetSupportedFormatsFunc func) {
64     mf_get_supported_formats_func_ = func;
65   }
set_direct_show_get_supported_formats_func_for_testing(GetSupportedFormatsFunc func)66   void set_direct_show_get_supported_formats_func_for_testing(
67       GetSupportedFormatsFunc func) {
68     direct_show_get_supported_formats_func_ = func;
69   }
70 
71  private:
72   void EnumerateDevicesUWP(
73       std::unique_ptr<VideoCaptureDeviceDescriptors> device_descriptors,
74       DeviceDescriptorsCallback result_callback);
75   void FoundAllDevicesUWP(
76       std::unique_ptr<VideoCaptureDeviceDescriptors> device_descriptors,
77       DeviceDescriptorsCallback result_callback,
78       IAsyncOperation<DeviceInformationCollection*>* operation);
79   void DeviceInfoReady(
80       std::unique_ptr<VideoCaptureDeviceDescriptors> device_descriptors,
81       DeviceDescriptorsCallback result_callback);
82   void GetDeviceDescriptorsMediaFoundation(
83       VideoCaptureDeviceDescriptors* device_descriptors);
84   void AugmentDescriptorListWithDirectShowOnlyDevices(
85       VideoCaptureDeviceDescriptors* device_descriptors);
86   bool EnumerateVideoDevicesMediaFoundation(
87       const std::vector<std::pair<GUID, GUID>>& attributes_data,
88       IMFActivate*** devices,
89       UINT32* count);
90   void GetDeviceDescriptorsDirectShow(
91       VideoCaptureDeviceDescriptors* device_descriptors);
92   int GetNumberOfSupportedFormats(const VideoCaptureDeviceDescriptor& device);
93   void GetApiSpecificSupportedFormats(
94       const VideoCaptureDeviceDescriptor& device,
95       VideoCaptureFormats* formats);
96 
97   bool use_media_foundation_;
98   MFSessionLifetime session_;
99   // In production code, when Media Foundation libraries are available,
100   // |mf_enum_device_sources_func_| points to MFEnumDeviceSources. It enables
101   // mock of Media Foundation API in unit tests.
102   MFEnumDeviceSourcesFunc mf_enum_device_sources_func_ = nullptr;
103   DirectShowEnumDevicesFunc direct_show_enum_devices_func_;
104 
105   GetSupportedFormatsFunc mf_get_supported_formats_func_;
106   GetSupportedFormatsFunc direct_show_get_supported_formats_func_;
107 
108   // For calling WinRT methods on a COM initiated thread.
109   base::Thread com_thread_;
110   scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_;
111   std::unordered_set<IAsyncOperation<DeviceInformationCollection*>*> async_ops_;
112   base::WeakPtrFactory<VideoCaptureDeviceFactoryWin> weak_ptr_factory_{this};
113 
114   DISALLOW_COPY_AND_ASSIGN(VideoCaptureDeviceFactoryWin);
115 };
116 
117 }  // namespace media
118 
119 #endif  // MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_FACTORY_WIN_H_
120