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 9namespace media { 10 11// Implement IEnumPins. 12class PinEnumerator FINAL 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 pin_enum->AddRef(); 76 pin_enum->index_ = index_; 77 *clone = pin_enum; 78 return S_OK; 79 } 80 81 private: 82 scoped_refptr<FilterBase> filter_; 83 size_t index_; 84}; 85 86FilterBase::FilterBase() : state_(State_Stopped) { 87} 88 89FilterBase::~FilterBase() { 90} 91 92STDMETHODIMP FilterBase::EnumPins(IEnumPins** enum_pins) { 93 *enum_pins = new PinEnumerator(this); 94 (*enum_pins)->AddRef(); 95 return S_OK; 96} 97 98STDMETHODIMP FilterBase::FindPin(LPCWSTR id, IPin** pin) { 99 return E_NOTIMPL; 100} 101 102STDMETHODIMP FilterBase::QueryFilterInfo(FILTER_INFO* info) { 103 info->pGraph = owning_graph_; 104 info->achName[0] = L'\0'; 105 if (info->pGraph) 106 info->pGraph->AddRef(); 107 return S_OK; 108} 109 110STDMETHODIMP FilterBase::JoinFilterGraph(IFilterGraph* graph, LPCWSTR name) { 111 owning_graph_ = graph; 112 return S_OK; 113} 114 115STDMETHODIMP FilterBase::QueryVendorInfo(LPWSTR *pVendorInfo) { 116 return S_OK; 117} 118 119// Implement IMediaFilter. 120STDMETHODIMP FilterBase::Stop() { 121 state_ = State_Stopped; 122 return S_OK; 123} 124 125STDMETHODIMP FilterBase::Pause() { 126 state_ = State_Paused; 127 return S_OK; 128} 129 130STDMETHODIMP FilterBase::Run(REFERENCE_TIME start) { 131 state_ = State_Running; 132 return S_OK; 133} 134 135STDMETHODIMP FilterBase::GetState(DWORD msec_timeout, FILTER_STATE* state) { 136 *state = state_; 137 return S_OK; 138} 139 140STDMETHODIMP FilterBase::SetSyncSource(IReferenceClock* clock) { 141 return S_OK; 142} 143 144STDMETHODIMP FilterBase::GetSyncSource(IReferenceClock** clock) { 145 return E_NOTIMPL; 146} 147 148// Implement from IPersistent. 149STDMETHODIMP FilterBase::GetClassID(CLSID* class_id) { 150 NOTREACHED(); 151 return E_NOTIMPL; 152} 153 154// Implement IUnknown. 155STDMETHODIMP FilterBase::QueryInterface(REFIID id, void** object_ptr) { 156 if (id == IID_IMediaFilter || id == IID_IUnknown) { 157 *object_ptr = static_cast<IMediaFilter*>(this); 158 } else if (id == IID_IPersist) { 159 *object_ptr = static_cast<IPersist*>(this); 160 } else { 161 return E_NOINTERFACE; 162 } 163 AddRef(); 164 return S_OK; 165} 166 167ULONG STDMETHODCALLTYPE FilterBase::AddRef() { 168 base::RefCounted<FilterBase>::AddRef(); 169 return 1; 170} 171 172ULONG STDMETHODCALLTYPE FilterBase::Release() { 173 base::RefCounted<FilterBase>::Release(); 174 return 1; 175} 176 177} // namespace media 178