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 FINAL
13 : public IEnumPins,
14 public base::RefCounted<PinEnumerator> {
15 public:
PinEnumerator(FilterBase * filter)16 explicit PinEnumerator(FilterBase* filter)
17 : filter_(filter),
18 index_(0) {
19 }
20
~PinEnumerator()21 ~PinEnumerator() {
22 }
23
24 // IUnknown implementation.
STDMETHOD(QueryInterface)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
STDMETHOD_(ULONG,AddRef)34 STDMETHOD_(ULONG, AddRef)() {
35 base::RefCounted<PinEnumerator>::AddRef();
36 return 1;
37 }
38
STDMETHOD_(ULONG,Release)39 STDMETHOD_(ULONG, Release)() {
40 base::RefCounted<PinEnumerator>::Release();
41 return 1;
42 }
43
44 // Implement IEnumPins.
STDMETHOD(Next)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
STDMETHOD(Skip)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
STDMETHOD(Reset)68 STDMETHOD(Reset)() {
69 index_ = 0;
70 return S_OK;
71 }
72
STDMETHOD(Clone)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
FilterBase()86 FilterBase::FilterBase() : state_(State_Stopped) {
87 }
88
~FilterBase()89 FilterBase::~FilterBase() {
90 }
91
EnumPins(IEnumPins ** enum_pins)92 STDMETHODIMP FilterBase::EnumPins(IEnumPins** enum_pins) {
93 *enum_pins = new PinEnumerator(this);
94 (*enum_pins)->AddRef();
95 return S_OK;
96 }
97
FindPin(LPCWSTR id,IPin ** pin)98 STDMETHODIMP FilterBase::FindPin(LPCWSTR id, IPin** pin) {
99 return E_NOTIMPL;
100 }
101
QueryFilterInfo(FILTER_INFO * info)102 STDMETHODIMP 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
JoinFilterGraph(IFilterGraph * graph,LPCWSTR name)110 STDMETHODIMP FilterBase::JoinFilterGraph(IFilterGraph* graph, LPCWSTR name) {
111 owning_graph_ = graph;
112 return S_OK;
113 }
114
QueryVendorInfo(LPWSTR * pVendorInfo)115 STDMETHODIMP FilterBase::QueryVendorInfo(LPWSTR *pVendorInfo) {
116 return S_OK;
117 }
118
119 // Implement IMediaFilter.
Stop()120 STDMETHODIMP FilterBase::Stop() {
121 state_ = State_Stopped;
122 return S_OK;
123 }
124
Pause()125 STDMETHODIMP FilterBase::Pause() {
126 state_ = State_Paused;
127 return S_OK;
128 }
129
Run(REFERENCE_TIME start)130 STDMETHODIMP FilterBase::Run(REFERENCE_TIME start) {
131 state_ = State_Running;
132 return S_OK;
133 }
134
GetState(DWORD msec_timeout,FILTER_STATE * state)135 STDMETHODIMP FilterBase::GetState(DWORD msec_timeout, FILTER_STATE* state) {
136 *state = state_;
137 return S_OK;
138 }
139
SetSyncSource(IReferenceClock * clock)140 STDMETHODIMP FilterBase::SetSyncSource(IReferenceClock* clock) {
141 return S_OK;
142 }
143
GetSyncSource(IReferenceClock ** clock)144 STDMETHODIMP FilterBase::GetSyncSource(IReferenceClock** clock) {
145 return E_NOTIMPL;
146 }
147
148 // Implement from IPersistent.
GetClassID(CLSID * class_id)149 STDMETHODIMP FilterBase::GetClassID(CLSID* class_id) {
150 NOTREACHED();
151 return E_NOTIMPL;
152 }
153
154 // Implement IUnknown.
QueryInterface(REFIID id,void ** object_ptr)155 STDMETHODIMP 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
AddRef()167 ULONG STDMETHODCALLTYPE FilterBase::AddRef() {
168 base::RefCounted<FilterBase>::AddRef();
169 return 1;
170 }
171
Release()172 ULONG STDMETHODCALLTYPE FilterBase::Release() {
173 base::RefCounted<FilterBase>::Release();
174 return 1;
175 }
176
177 } // namespace media
178