Disable force-compositing-mode on background pages
[chromium-blink-merge.git] / media / video / capture / win / pin_base_win.cc
blob7e2f7b095ad3d368ea41069a3e5530977d506d7b
1 // Copyright (c) 2012 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.
5 #include "media/video/capture/win/pin_base_win.h"
7 #include "base/logging.h"
9 namespace media {
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) {
21 ~TypeEnumerator() {
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;
31 return E_NOINTERFACE;
34 STDMETHOD_(ULONG, AddRef)() {
35 base::RefCounted<TypeEnumerator>::AddRef();
36 return 1;
39 STDMETHOD_(ULONG, Release)() {
40 base::RefCounted<TypeEnumerator>::Release();
41 return 1;
44 // Implement IEnumMediaTypes.
45 STDMETHOD(Next)(ULONG count, AM_MEDIA_TYPE** types, ULONG* fetched) {
46 ULONG types_fetched = 0;
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;
56 ZeroMemory(type, sizeof(AM_MEDIA_TYPE));
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;
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;
78 if (fetched)
79 *fetched = types_fetched;
81 return types_fetched == count ? S_OK : S_FALSE;
84 STDMETHOD(Skip)(ULONG count) {
85 index_ += count;
86 return S_OK;
89 STDMETHOD(Reset)() {
90 index_ = 0;
91 return S_OK;
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;
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]);
112 scoped_refptr<PinBase> pin_;
113 int index_;
116 PinBase::PinBase(IBaseFilter* owner)
117 : owner_(owner) {
118 memset(&current_media_type_, 0, sizeof(current_media_type_));
121 PinBase::~PinBase() {
124 void PinBase::SetOwner(IBaseFilter* owner) {
125 owner_ = owner;
128 // Called on an output pin to and establish a
129 // connection.
130 STDMETHODIMP PinBase::Connect(IPin* receive_pin,
131 const AM_MEDIA_TYPE* media_type) {
132 if (!receive_pin || !media_type)
133 return E_POINTER;
135 current_media_type_ = *media_type;
136 receive_pin->AddRef();
137 connected_pin_.Attach(receive_pin);
138 HRESULT hr = receive_pin->ReceiveConnection(this, media_type);
140 return hr;
143 // Called from an output pin on an input pin to and establish a
144 // connection.
145 STDMETHODIMP PinBase::ReceiveConnection(IPin* connector,
146 const AM_MEDIA_TYPE* media_type) {
147 if (!IsMediaTypeValid(media_type))
148 return VFW_E_TYPE_NOT_ACCEPTED;
150 current_media_type_ = *media_type;
151 connector->AddRef();
152 connected_pin_.Attach(connector);
153 return S_OK;
156 STDMETHODIMP PinBase::Disconnect() {
157 if (!connected_pin_)
158 return S_FALSE;
160 connected_pin_.Release();
161 return S_OK;
164 STDMETHODIMP PinBase::ConnectedTo(IPin** pin) {
165 *pin = connected_pin_;
166 if (!connected_pin_)
167 return VFW_E_NOT_CONNECTED;
169 connected_pin_.get()->AddRef();
170 return S_OK;
173 STDMETHODIMP PinBase::ConnectionMediaType(AM_MEDIA_TYPE* media_type) {
174 if (!connected_pin_)
175 return VFW_E_NOT_CONNECTED;
176 *media_type = current_media_type_;
177 return S_OK;
180 STDMETHODIMP PinBase::QueryPinInfo(PIN_INFO* info) {
181 info->dir = PINDIR_INPUT;
182 info->pFilter = owner_;
183 if (owner_)
184 owner_->AddRef();
185 info->achName[0] = L'\0';
187 return S_OK;
190 STDMETHODIMP PinBase::QueryDirection(PIN_DIRECTION* pin_dir) {
191 *pin_dir = PINDIR_INPUT;
192 return S_OK;
195 STDMETHODIMP PinBase::QueryId(LPWSTR* id) {
196 NOTREACHED();
197 return E_OUTOFMEMORY;
200 STDMETHODIMP PinBase::QueryAccept(const AM_MEDIA_TYPE* media_type) {
201 return S_FALSE;
204 STDMETHODIMP PinBase::EnumMediaTypes(IEnumMediaTypes** types) {
205 *types = new TypeEnumerator(this);
206 (*types)->AddRef();
207 return S_OK;
210 STDMETHODIMP PinBase::QueryInternalConnections(IPin** pins, ULONG* no_pins) {
211 return E_NOTIMPL;
214 STDMETHODIMP PinBase::EndOfStream() {
215 return S_OK;
218 STDMETHODIMP PinBase::BeginFlush() {
219 return S_OK;
222 STDMETHODIMP PinBase::EndFlush() {
223 return S_OK;
226 STDMETHODIMP PinBase::NewSegment(REFERENCE_TIME start,
227 REFERENCE_TIME stop,
228 double rate) {
229 NOTREACHED();
230 return E_NOTIMPL;
233 // Inherited from IMemInputPin.
234 STDMETHODIMP PinBase::GetAllocator(IMemAllocator** allocator) {
235 return VFW_E_NO_ALLOCATOR;
238 STDMETHODIMP PinBase::NotifyAllocator(IMemAllocator* allocator,
239 BOOL read_only) {
240 return S_OK;
243 STDMETHODIMP PinBase::GetAllocatorRequirements(
244 ALLOCATOR_PROPERTIES* properties) {
245 return E_NOTIMPL;
248 STDMETHODIMP PinBase::ReceiveMultiple(IMediaSample** samples,
249 long sample_count,
250 long* processed) {
251 NOTREACHED();
252 return VFW_E_INVALIDMEDIATYPE;
255 STDMETHODIMP PinBase::ReceiveCanBlock() {
256 return S_FALSE;
259 // Inherited from IUnknown.
260 STDMETHODIMP PinBase::QueryInterface(REFIID id, void** object_ptr) {
261 if (id == IID_IPin || id == IID_IUnknown) {
262 *object_ptr = static_cast<IPin*>(this);
263 } else if (id == IID_IMemInputPin) {
264 *object_ptr = static_cast<IMemInputPin*>(this);
265 } else {
266 return E_NOINTERFACE;
268 AddRef();
269 return S_OK;
272 STDMETHODIMP_(ULONG) PinBase::AddRef() {
273 base::RefCounted<PinBase>::AddRef();
274 return 1;
277 STDMETHODIMP_(ULONG) PinBase::Release() {
278 base::RefCounted<PinBase>::Release();
279 return 1;
282 } // namespace media