1 // Copyright (c) 2012 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 // Windows specific implementation of VideoCaptureDevice. 6 // MediaFoundation is used for capturing. MediaFoundation provides its own 7 // threads for capturing. 8 9 #ifndef MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_MF_WIN_H_ 10 #define MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_MF_WIN_H_ 11 12 #include <mfcaptureengine.h> 13 #include <mfidl.h> 14 #include <mfreadwrite.h> 15 #include <stdint.h> 16 #include <strmif.h> 17 #include <wrl/client.h> 18 19 #include <vector> 20 21 #include "base/callback_forward.h" 22 #include "base/macros.h" 23 #include "base/optional.h" 24 #include "base/sequence_checker.h" 25 #include "media/capture/capture_export.h" 26 #include "media/capture/video/video_capture_device.h" 27 #include "media/capture/video/win/capability_list_win.h" 28 #include "media/capture/video/win/metrics.h" 29 #include "media/capture/video/win/video_capture_dxgi_device_manager.h" 30 31 interface IMFSourceReader; 32 33 namespace base { 34 class Location; 35 } // namespace base 36 37 namespace media { 38 39 class MFVideoCallback; 40 41 class CAPTURE_EXPORT VideoCaptureDeviceMFWin : public VideoCaptureDevice { 42 public: 43 static bool GetPixelFormatFromMFSourceMediaSubtype(const GUID& guid, 44 bool use_hardware_format, 45 VideoPixelFormat* format); 46 static VideoCaptureControlSupport GetControlSupport( 47 Microsoft::WRL::ComPtr<IMFMediaSource> source); 48 49 explicit VideoCaptureDeviceMFWin( 50 const VideoCaptureDeviceDescriptor& device_descriptor, 51 Microsoft::WRL::ComPtr<IMFMediaSource> source, 52 scoped_refptr<VideoCaptureDXGIDeviceManager> dxgi_device_manager); 53 explicit VideoCaptureDeviceMFWin( 54 const VideoCaptureDeviceDescriptor& device_descriptor, 55 Microsoft::WRL::ComPtr<IMFMediaSource> source, 56 scoped_refptr<VideoCaptureDXGIDeviceManager> dxgi_device_manager, 57 Microsoft::WRL::ComPtr<IMFCaptureEngine> engine); 58 59 ~VideoCaptureDeviceMFWin() override; 60 61 // Opens the device driver for this device. 62 bool Init(); 63 64 // VideoCaptureDevice implementation. 65 void AllocateAndStart( 66 const VideoCaptureParams& params, 67 std::unique_ptr<VideoCaptureDevice::Client> client) override; 68 void StopAndDeAllocate() override; 69 void TakePhoto(TakePhotoCallback callback) override; 70 void GetPhotoState(GetPhotoStateCallback callback) override; 71 void SetPhotoOptions(mojom::PhotoSettingsPtr settings, 72 SetPhotoOptionsCallback callback) override; 73 74 // Captured new video data. 75 void OnIncomingCapturedData(const uint8_t* data, 76 int length, 77 base::TimeTicks reference_time, 78 base::TimeDelta timestamp); 79 void OnFrameDropped(VideoCaptureFrameDropReason reason); 80 void OnEvent(IMFMediaEvent* media_event); 81 82 using CreateMFPhotoCallbackCB = 83 base::RepeatingCallback<scoped_refptr<IMFCaptureEngineOnSampleCallback>( 84 VideoCaptureDevice::TakePhotoCallback callback, 85 VideoCaptureFormat format)>; 86 get_use_photo_stream_to_take_photo_for_testing()87 bool get_use_photo_stream_to_take_photo_for_testing() { 88 return !photo_capabilities_.empty(); 89 } 90 set_create_mf_photo_callback_for_testing(CreateMFPhotoCallbackCB cb)91 void set_create_mf_photo_callback_for_testing(CreateMFPhotoCallbackCB cb) { 92 create_mf_photo_callback_ = cb; 93 } 94 set_max_retry_count_for_testing(int max_retry_count)95 void set_max_retry_count_for_testing(int max_retry_count) { 96 max_retry_count_ = max_retry_count; 97 } 98 set_retry_delay_in_ms_for_testing(int retry_delay_in_ms)99 void set_retry_delay_in_ms_for_testing(int retry_delay_in_ms) { 100 retry_delay_in_ms_ = retry_delay_in_ms; 101 } 102 set_dxgi_device_manager_for_testing(scoped_refptr<VideoCaptureDXGIDeviceManager> dxgi_device_manager)103 void set_dxgi_device_manager_for_testing( 104 scoped_refptr<VideoCaptureDXGIDeviceManager> dxgi_device_manager) { 105 dxgi_device_manager_ = std::move(dxgi_device_manager); 106 } 107 camera_rotation()108 base::Optional<int> camera_rotation() const { return camera_rotation_; } 109 110 private: 111 HRESULT ExecuteHresultCallbackWithRetries( 112 base::RepeatingCallback<HRESULT()> callback, 113 MediaFoundationFunctionRequiringRetry which_function); 114 HRESULT GetDeviceStreamCount(IMFCaptureSource* source, DWORD* count); 115 HRESULT GetDeviceStreamCategory( 116 IMFCaptureSource* source, 117 DWORD stream_index, 118 MF_CAPTURE_ENGINE_STREAM_CATEGORY* stream_category); 119 HRESULT GetAvailableDeviceMediaType(IMFCaptureSource* source, 120 DWORD stream_index, 121 DWORD media_type_index, 122 IMFMediaType** type); 123 124 HRESULT FillCapabilities(IMFCaptureSource* source, 125 bool photo, 126 CapabilityList* capabilities); 127 void OnError(VideoCaptureError error, 128 const base::Location& from_here, 129 HRESULT hr); 130 void OnError(VideoCaptureError error, 131 const base::Location& from_here, 132 const char* message); 133 void SendOnStartedIfNotYetSent(); 134 HRESULT WaitOnCaptureEvent(GUID capture_event_guid); 135 136 VideoFacingMode facing_mode_; 137 CreateMFPhotoCallbackCB create_mf_photo_callback_; 138 scoped_refptr<MFVideoCallback> video_callback_; 139 bool is_initialized_; 140 int max_retry_count_; 141 int retry_delay_in_ms_; 142 143 // Guards the below variables from concurrent access between methods running 144 // on |sequence_checker_| and calls to OnIncomingCapturedData() and OnEvent() 145 // made by MediaFoundation on threads outside of our control. 146 base::Lock lock_; 147 148 std::unique_ptr<VideoCaptureDevice::Client> client_; 149 const Microsoft::WRL::ComPtr<IMFMediaSource> source_; 150 Microsoft::WRL::ComPtr<IAMCameraControl> camera_control_; 151 Microsoft::WRL::ComPtr<IAMVideoProcAmp> video_control_; 152 Microsoft::WRL::ComPtr<IMFCaptureEngine> engine_; 153 std::unique_ptr<CapabilityWin> selected_video_capability_; 154 CapabilityList photo_capabilities_; 155 std::unique_ptr<CapabilityWin> selected_photo_capability_; 156 bool is_started_; 157 bool has_sent_on_started_to_client_; 158 // These flags keep the manual/auto mode between cycles of SetPhotoOptions(). 159 bool exposure_mode_manual_; 160 bool focus_mode_manual_; 161 bool white_balance_mode_manual_; 162 base::queue<TakePhotoCallback> video_stream_take_photo_callbacks_; 163 base::WaitableEvent capture_initialize_; 164 base::WaitableEvent capture_error_; 165 scoped_refptr<VideoCaptureDXGIDeviceManager> dxgi_device_manager_; 166 base::Optional<int> camera_rotation_; 167 168 SEQUENCE_CHECKER(sequence_checker_); 169 170 DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureDeviceMFWin); 171 }; 172 173 } // namespace media 174 175 #endif // MEDIA_CAPTURE_VIDEO_WIN_VIDEO_CAPTURE_DEVICE_MF_WIN_H_ 176