1 /* 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef MODULES_VIDEO_CAPTURE_MAIN_SOURCE_WINDOWS_SINK_FILTER_DS_H_ 12 #define MODULES_VIDEO_CAPTURE_MAIN_SOURCE_WINDOWS_SINK_FILTER_DS_H_ 13 14 #include <dshow.h> 15 16 #include <atomic> 17 #include <memory> 18 #include <vector> 19 20 #include "modules/video_capture/video_capture_impl.h" 21 #include "modules/video_capture/windows/help_functions_ds.h" 22 #include "rtc_base/thread_annotations.h" 23 #include "rtc_base/thread_checker.h" 24 25 namespace webrtc { 26 namespace videocapturemodule { 27 // forward declarations 28 class CaptureSinkFilter; 29 30 // Input pin for camera input 31 // Implements IMemInputPin, IPin. 32 class CaptureInputPin : public IMemInputPin, public IPin { 33 public: 34 CaptureInputPin(CaptureSinkFilter* filter); 35 36 HRESULT SetRequestedCapability(const VideoCaptureCapability& capability); 37 38 // Notifications from the filter. 39 void OnFilterActivated(); 40 void OnFilterDeactivated(); 41 42 protected: 43 virtual ~CaptureInputPin(); 44 45 private: 46 CaptureSinkFilter* Filter() const; 47 48 HRESULT AttemptConnection(IPin* receive_pin, const AM_MEDIA_TYPE* media_type); 49 std::vector<AM_MEDIA_TYPE*> DetermineCandidateFormats( 50 IPin* receive_pin, 51 const AM_MEDIA_TYPE* media_type); 52 void ClearAllocator(bool decommit); 53 HRESULT CheckDirection(IPin* pin) const; 54 55 // IUnknown 56 STDMETHOD(QueryInterface)(REFIID riid, void** ppv) override; 57 58 // clang-format off 59 // clang isn't sure what to do with the longer STDMETHOD() function 60 // declarations. 61 62 // IPin 63 STDMETHOD(Connect)(IPin* receive_pin, 64 const AM_MEDIA_TYPE* media_type) override; 65 STDMETHOD(ReceiveConnection)(IPin* connector, 66 const AM_MEDIA_TYPE* media_type) override; 67 STDMETHOD(Disconnect)() override; 68 STDMETHOD(ConnectedTo)(IPin** pin) override; 69 STDMETHOD(ConnectionMediaType)(AM_MEDIA_TYPE* media_type) override; 70 STDMETHOD(QueryPinInfo)(PIN_INFO* info) override; 71 STDMETHOD(QueryDirection)(PIN_DIRECTION* pin_dir) override; 72 STDMETHOD(QueryId)(LPWSTR* id) override; 73 STDMETHOD(QueryAccept)(const AM_MEDIA_TYPE* media_type) override; 74 STDMETHOD(EnumMediaTypes)(IEnumMediaTypes** types) override; 75 STDMETHOD(QueryInternalConnections)(IPin** pins, ULONG* count) override; 76 STDMETHOD(EndOfStream)() override; 77 STDMETHOD(BeginFlush)() override; 78 STDMETHOD(EndFlush)() override; 79 STDMETHOD(NewSegment)(REFERENCE_TIME start, REFERENCE_TIME stop, 80 double rate) override; 81 82 // IMemInputPin 83 STDMETHOD(GetAllocator)(IMemAllocator** allocator) override; 84 STDMETHOD(NotifyAllocator)(IMemAllocator* allocator, BOOL read_only) override; 85 STDMETHOD(GetAllocatorRequirements)(ALLOCATOR_PROPERTIES* props) override; 86 STDMETHOD(Receive)(IMediaSample* sample) override; 87 STDMETHOD(ReceiveMultiple)(IMediaSample** samples, long count, 88 long* processed) override; 89 STDMETHOD(ReceiveCanBlock)() override; 90 // clang-format on 91 92 rtc::ThreadChecker main_checker_; 93 rtc::ThreadChecker capture_checker_; 94 95 VideoCaptureCapability requested_capability_ RTC_GUARDED_BY(main_checker_); 96 // Accessed on the main thread when Filter()->IsStopped() (capture thread not 97 // running), otherwise accessed on the capture thread. 98 VideoCaptureCapability resulting_capability_; 99 DWORD capture_thread_id_ = 0; 100 rtc::scoped_refptr<IMemAllocator> allocator_ RTC_GUARDED_BY(main_checker_); 101 rtc::scoped_refptr<IPin> receive_pin_ RTC_GUARDED_BY(main_checker_); 102 std::atomic_bool flushing_{false}; 103 std::atomic_bool runtime_error_{false}; 104 // Holds a referenceless pointer to the owning filter, the name and 105 // direction of the pin. The filter pointer can be considered const. 106 PIN_INFO info_ = {}; 107 AM_MEDIA_TYPE media_type_ RTC_GUARDED_BY(main_checker_) = {}; 108 }; 109 110 // Implement IBaseFilter (including IPersist and IMediaFilter). 111 class CaptureSinkFilter : public IBaseFilter { 112 public: 113 CaptureSinkFilter(VideoCaptureImpl* capture_observer); 114 115 HRESULT SetRequestedCapability(const VideoCaptureCapability& capability); 116 117 // Called on the capture thread. 118 void ProcessCapturedFrame(unsigned char* buffer, 119 size_t length, 120 const VideoCaptureCapability& frame_info); 121 122 void NotifyEvent(long code, LONG_PTR param1, LONG_PTR param2); 123 bool IsStopped() const; 124 125 // IUnknown 126 STDMETHOD(QueryInterface)(REFIID riid, void** ppv) override; 127 128 // IPersist 129 STDMETHOD(GetClassID)(CLSID* clsid) override; 130 131 // IMediaFilter. 132 STDMETHOD(GetState)(DWORD msecs, FILTER_STATE* state) override; 133 STDMETHOD(SetSyncSource)(IReferenceClock* clock) override; 134 STDMETHOD(GetSyncSource)(IReferenceClock** clock) override; 135 STDMETHOD(Pause)() override; 136 STDMETHOD(Run)(REFERENCE_TIME start) override; 137 STDMETHOD(Stop)() override; 138 139 // IBaseFilter 140 STDMETHOD(EnumPins)(IEnumPins** pins) override; 141 STDMETHOD(FindPin)(LPCWSTR id, IPin** pin) override; 142 STDMETHOD(QueryFilterInfo)(FILTER_INFO* info) override; 143 STDMETHOD(JoinFilterGraph)(IFilterGraph* graph, LPCWSTR name) override; 144 STDMETHOD(QueryVendorInfo)(LPWSTR* vendor_info) override; 145 146 protected: 147 virtual ~CaptureSinkFilter(); 148 149 private: 150 rtc::ThreadChecker main_checker_; 151 const rtc::scoped_refptr<ComRefCount<CaptureInputPin>> input_pin_; 152 VideoCaptureImpl* const capture_observer_; 153 FILTER_INFO info_ RTC_GUARDED_BY(main_checker_) = {}; 154 // Set/cleared in JoinFilterGraph. The filter must be stopped (no capture) 155 // at that time, so no lock is required. While the state is not stopped, 156 // the sink will be used from the capture thread. 157 IMediaEventSink* sink_ = nullptr; 158 FILTER_STATE state_ RTC_GUARDED_BY(main_checker_) = State_Stopped; 159 }; 160 } // namespace videocapturemodule 161 } // namespace webrtc 162 #endif // MODULES_VIDEO_CAPTURE_MAIN_SOURCE_WINDOWS_SINK_FILTER_DS_H_ 163