1 // Copyright (c) 2011 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 #include "media/video/capture/win/filter_base_win.h" 6 7 #pragma comment(lib, "strmiids.lib") 8 9 namespace media { 10 11 // Implement IEnumPins. 12 class PinEnumerator 13 : public IEnumPins, 14 public base::RefCounted<PinEnumerator> { 15 public: 16 explicit PinEnumerator(FilterBase* filter) 17 : filter_(filter), 18 index_(0) { 19 } 20 21 ~PinEnumerator() { 22 } 23 24 // IUnknown implementation. 25 STDMETHOD(QueryInterface)(REFIID iid, void** object_ptr) { 26 if (iid == IID_IEnumPins || iid == IID_IUnknown) { 27 AddRef(); 28 *object_ptr = static_cast<IEnumPins*>(this); 29 return S_OK; 30 } 31 return E_NOINTERFACE; 32 } 33 34 STDMETHOD_(ULONG, AddRef)() { 35 base::RefCounted<PinEnumerator>::AddRef(); 36 return 1; 37 } 38 39 STDMETHOD_(ULONG, Release)() { 40 base::RefCounted<PinEnumerator>::Release(); 41 return 1; 42 } 43 44 // Implement IEnumPins. 45 STDMETHOD(Next)(ULONG count, IPin** pins, ULONG* fetched) { 46 ULONG pins_fetched = 0; 47 while (pins_fetched < count && filter_->NoOfPins() > index_) { 48 IPin* pin = filter_->GetPin(index_++); 49 pin->AddRef(); 50 pins[pins_fetched++] = pin; 51 } 52 53 if (fetched) 54 *fetched = pins_fetched; 55 56 return pins_fetched == count ? S_OK : S_FALSE; 57 } 58 59 STDMETHOD(Skip)(ULONG count) { 60 if (filter_->NoOfPins()- index_ > count) { 61 index_ += count; 62 return S_OK; 63 } 64 index_ = 0; 65 return S_FALSE; 66 } 67 68 STDMETHOD(Reset)() { 69 index_ = 0; 70 return S_OK; 71 } 72 73 STDMETHOD(Clone)(IEnumPins** clone) { 74 PinEnumerator* pin_enum = new PinEnumerator(filter_); 75 if (!pin_enum) 76 return E_OUTOFMEMORY; 77 pin_enum->AddRef(); 78 pin_enum->index_ = index_; 79 *clone = pin_enum; 80 return S_OK; 81 } 82 83 private: 84 scoped_refptr<FilterBase> filter_; 85 size_t index_; 86 }; 87 88 FilterBase::FilterBase() : state_(State_Stopped) { 89 } 90 91 FilterBase::~FilterBase() { 92 } 93 94 STDMETHODIMP FilterBase::EnumPins(IEnumPins** enum_pins) { 95 *enum_pins = new PinEnumerator(this); 96 (*enum_pins)->AddRef(); 97 return S_OK; 98 } 99 100 STDMETHODIMP FilterBase::FindPin(LPCWSTR id, IPin** pin) { 101 return E_NOTIMPL; 102 } 103 104 STDMETHODIMP FilterBase::QueryFilterInfo(FILTER_INFO* info) { 105 info->pGraph = owning_graph_; 106 info->achName[0] = L'\0'; 107 if (info->pGraph) 108 info->pGraph->AddRef(); 109 return S_OK; 110 } 111 112 STDMETHODIMP FilterBase::JoinFilterGraph(IFilterGraph* graph, LPCWSTR name) { 113 owning_graph_ = graph; 114 return S_OK; 115 } 116 117 STDMETHODIMP FilterBase::QueryVendorInfo(LPWSTR *pVendorInfo) { 118 return S_OK; 119 } 120 121 // Implement IMediaFilter. 122 STDMETHODIMP FilterBase::Stop() { 123 state_ = State_Stopped; 124 return S_OK; 125 } 126 127 STDMETHODIMP FilterBase::Pause() { 128 state_ = State_Paused; 129 return S_OK; 130 } 131 132 STDMETHODIMP FilterBase::Run(REFERENCE_TIME start) { 133 state_ = State_Running; 134 return S_OK; 135 } 136 137 STDMETHODIMP FilterBase::GetState(DWORD msec_timeout, FILTER_STATE* state) { 138 *state = state_; 139 return S_OK; 140 } 141 142 STDMETHODIMP FilterBase::SetSyncSource(IReferenceClock* clock) { 143 return S_OK; 144 } 145 146 STDMETHODIMP FilterBase::GetSyncSource(IReferenceClock** clock) { 147 return E_NOTIMPL; 148 } 149 150 // Implement from IPersistent. 151 STDMETHODIMP FilterBase::GetClassID(CLSID* class_id) { 152 NOTREACHED(); 153 return E_NOTIMPL; 154 } 155 156 // Implement IUnknown. 157 STDMETHODIMP FilterBase::QueryInterface(REFIID id, void** object_ptr) { 158 if (id == IID_IMediaFilter || id == IID_IUnknown) { 159 *object_ptr = static_cast<IMediaFilter*>(this); 160 } else if (id == IID_IPersist) { 161 *object_ptr = static_cast<IPersist*>(this); 162 } else { 163 return E_NOINTERFACE; 164 } 165 AddRef(); 166 return S_OK; 167 } 168 169 ULONG STDMETHODCALLTYPE FilterBase::AddRef() { 170 base::RefCounted<FilterBase>::AddRef(); 171 return 1; 172 } 173 174 ULONG STDMETHODCALLTYPE FilterBase::Release() { 175 base::RefCounted<FilterBase>::Release(); 176 return 1; 177 } 178 179 } // namespace media 180