Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1337)

Side by Side Diff: media/video/capture/win/pin_base_win.cc

Issue 7229013: This is the VideoCaptureDevice implementation for windows. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Fixed reference count issue found by Tommi. Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/pin_base_win.h"
6
7 #include "base/logging.h"
8
9 namespace media {
10
11 // Implement IEnumPins.
12 class TypeEnumerator
13 : public IEnumMediaTypes,
14 public base::RefCounted<TypeEnumerator> {
15 public:
16 explicit TypeEnumerator(PinBase* pin)
17 : pin_(pin),
18 index_(0) {
19 }
20
21 ~TypeEnumerator() {
22 }
23
24 // Implement from IUnknown.
25 STDMETHOD(QueryInterface)(REFIID iid, void** object_ptr) {
26 if (iid == IID_IEnumMediaTypes || iid == IID_IUnknown) {
27 AddRef();
28 *object_ptr = static_cast<IEnumMediaTypes*>(this);
29 return S_OK;
30 }
31 return E_NOINTERFACE;
32 }
33
34 STDMETHOD_(ULONG, AddRef)() {
35 base::RefCounted<TypeEnumerator>::AddRef();
36 return 1;
37 }
38
39 STDMETHOD_(ULONG, Release)() {
40 base::RefCounted<TypeEnumerator>::Release();
41 return 1;
42 }
43
44 // Implement IEnumMediaTypes.
45 STDMETHOD(Next)(ULONG count, AM_MEDIA_TYPE** types, ULONG* fetched) {
46 ULONG types_fetched = 0;
47
48 while (types_fetched < count) {
49 // Allocate AM_MEDIA_TYPE that we will store the media type in.
50 AM_MEDIA_TYPE* type = reinterpret_cast<AM_MEDIA_TYPE*>(CoTaskMemAlloc(
51 sizeof(AM_MEDIA_TYPE)));
52 if (!type) {
53 FreeAllocatedMediaTypes(types_fetched, types);
54 return E_OUTOFMEMORY;
55 }
56 ZeroMemory(type, sizeof(AM_MEDIA_TYPE));
57
58 // Allocate a VIDEOINFOHEADER and connect it to the AM_MEDIA_TYPE.
59 type->cbFormat = sizeof(VIDEOINFOHEADER);
60 BYTE *format = reinterpret_cast<BYTE*>(CoTaskMemAlloc(
61 sizeof(VIDEOINFOHEADER)));
62 if (!format) {
63 CoTaskMemFree(type);
64 FreeAllocatedMediaTypes(types_fetched, types);
65 return E_OUTOFMEMORY;
66 }
67 type->pbFormat = format;
68 // Get the media type from the pin.
69 if (pin_->GetValidMediaType(index_++, type)) {
70 types[types_fetched++] = type;
71 } else {
72 CoTaskMemFree(format);
73 CoTaskMemFree(type);
74 break;
75 }
76 }
77
78 if (fetched)
79 *fetched = types_fetched;
80
81 return types_fetched == count ? S_OK : S_FALSE;
82 }
83
84 STDMETHOD(Skip)(ULONG count) {
85 index_ += count;
86 return S_OK;
87 }
88
89 STDMETHOD(Reset)() {
90 index_ = 0;
91 return S_OK;
92 }
93
94 STDMETHOD(Clone)(IEnumMediaTypes** clone) {
95 TypeEnumerator* type_enum = new TypeEnumerator(pin_);
96 if (!type_enum)
97 return E_OUTOFMEMORY;
98 type_enum->AddRef();
99 type_enum->index_ = index_;
100 *clone = type_enum;
101 return S_OK;
102 }
103
104 private:
105 void FreeAllocatedMediaTypes(ULONG allocated, AM_MEDIA_TYPE** types) {
106 for (ULONG i = 0; i < allocated; ++i) {
107 CoTaskMemFree(types[i]->pbFormat);
108 CoTaskMemFree(types[i]);
109 }
110 }
111
112 scoped_refptr<PinBase> pin_;
113 int index_;
114 };
115
116 PinBase::PinBase(IBaseFilter* owner)
117 : owner_(owner) {
118 }
119
120 PinBase::~PinBase() {
121 }
122
123 void PinBase::SetOwner(IBaseFilter* owner) {
124 owner_ = owner;
125 }
126
127 // Called on an output pin to and establish a
128 // connection.
129 STDMETHODIMP PinBase::Connect(IPin* receive_pin, const AM_MEDIA_TYPE* mt) {
130 if (!receive_pin || !mt)
131 return E_POINTER;
132
133 current_media_type_ = *mt;
134 receive_pin->AddRef();
135 connected_pin_.Attach(receive_pin);
136 HRESULT hr = receive_pin->ReceiveConnection(this, mt);
137
138 return hr;
139 }
140
141 // Called from an output pin on an input pin to and establish a
142 // connection.
143 STDMETHODIMP PinBase::ReceiveConnection(IPin* connector,
144 const AM_MEDIA_TYPE* mt) {
145 if (IsMediaTypeValid(mt)) {
146 current_media_type_ = current_media_type_;
cpu_(ooo_6.6-7.5) 2011/06/27 18:10:27 nit: The negative logic is more readable, prefer i
Per K 2011/06/28 10:14:07 Done.
147 connector->AddRef();
148 connected_pin_.Attach(connector);
149 return S_OK;
150 }
151 return VFW_E_TYPE_NOT_ACCEPTED;
152 }
153
154 STDMETHODIMP PinBase::Disconnect() {
155 if (connected_pin_) {
156 connected_pin_.Release();
cpu_(ooo_6.6-7.5) 2011/06/27 18:10:27 same nit as 145 and elsewhere.
Per K 2011/06/28 10:14:07 Done.
157 return S_OK;
158 }
159 return S_FALSE;
160 }
161
162 STDMETHODIMP PinBase::ConnectedTo(IPin** pin) {
163 *pin = connected_pin_;
164 if (connected_pin_ != NULL) {
165 connected_pin_.get()->AddRef();
166 return S_OK;
167 }
168 return VFW_E_NOT_CONNECTED;
169 }
170
171 STDMETHODIMP PinBase::ConnectionMediaType(AM_MEDIA_TYPE* mt) {
172 if (!connected_pin_)
173 return VFW_E_NOT_CONNECTED;
174 *mt = current_media_type_;
175 return S_OK;
176 }
177
178 STDMETHODIMP PinBase::QueryPinInfo(PIN_INFO* info) {
179 DCHECK(info);
cpu_(ooo_6.6-7.5) 2011/06/27 18:10:27 In general I avoid this pattern DCHECK(foo); foo-
Per K 2011/06/28 10:14:07 Done.
180 info->dir = PINDIR_INPUT;
181 info->pFilter = owner_;
182 if (owner_)
183 owner_->AddRef();
184 info->achName[0] = L'\0';
185
186 return S_OK;
187 }
188
189 STDMETHODIMP PinBase::QueryDirection(PIN_DIRECTION* pin_dir) {
190 *pin_dir = PINDIR_INPUT;
191 return S_OK;
192 }
193
194 STDMETHODIMP PinBase::QueryId(LPWSTR* id) {
195 NOTREACHED();
196 return E_OUTOFMEMORY;
197 }
198
199 STDMETHODIMP PinBase::QueryAccept(const AM_MEDIA_TYPE* mt) {
200 return S_FALSE;
201 }
202
203 STDMETHODIMP PinBase::EnumMediaTypes(IEnumMediaTypes** types) {
204 *types = new TypeEnumerator(this);
205 (*types)->AddRef();
206 return S_OK;
207 }
208
209 STDMETHODIMP PinBase::QueryInternalConnections(IPin** pins, ULONG* count) {
210 return E_NOTIMPL;
211 }
212
213 STDMETHODIMP PinBase::EndOfStream() {
214 return S_OK;
215 }
216
217 STDMETHODIMP PinBase::BeginFlush() {
218 return S_OK;
219 }
220
221 STDMETHODIMP PinBase::EndFlush() {
222 return S_OK;
223 }
224
225 STDMETHODIMP PinBase::NewSegment(REFERENCE_TIME start,
226 REFERENCE_TIME stop,
227 double rate) {
228 NOTREACHED();
229 return E_NOTIMPL;
230 }
231
232 // Inherited from IMemInputPin.
233 STDMETHODIMP PinBase::GetAllocator(IMemAllocator** allocator) {
234 return VFW_E_NO_ALLOCATOR;
235 }
236
237 STDMETHODIMP PinBase::NotifyAllocator(IMemAllocator* allocator,
238 BOOL read_only) {
239 return S_OK;
240 }
241
242 STDMETHODIMP PinBase::GetAllocatorRequirements(
243 ALLOCATOR_PROPERTIES* properties) {
244 return E_NOTIMPL;
245 }
246
247 STDMETHODIMP PinBase::ReceiveMultiple(IMediaSample** samples,
248 long sample_count,
249 long* processed) {
250 NOTREACHED();
251 return VFW_E_INVALIDMEDIATYPE;
252 }
253
254 STDMETHODIMP PinBase::ReceiveCanBlock() {
255 return S_FALSE;
256 }
257
258 // Inherited from IUnknown.
259 STDMETHODIMP PinBase::QueryInterface(REFIID id, void** object_ptr) {
260 if (id == IID_IPin || id == IID_IUnknown) {
261 AddRef();
262 *object_ptr = static_cast<IPin*>(this);
263 } else if (id == IID_IMemInputPin) {
264 AddRef();
cpu_(ooo_6.6-7.5) 2011/06/27 18:10:27 same
Per K 2011/06/28 10:14:07 Done.
265 *object_ptr = static_cast<IMemInputPin*>(this);
266 } else {
267 return E_NOINTERFACE;
268 }
269 return S_OK;
270 }
271
272 STDMETHODIMP_(ULONG) PinBase::AddRef() {
273 base::RefCounted<PinBase>::AddRef();
274 return 1;
275 }
276
277 STDMETHODIMP_(ULONG) PinBase::Release() {
278 base::RefCounted<PinBase>::Release();
279 return 1;
280 }
281
282 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698