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

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

Issue 276383002: VideoCaptureDeviceWin: Extract class-static method into a Factory (both MF/DS) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 7 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/video/capture/win/video_capture_device_win.h" 5 #include "media/video/capture/win/video_capture_device_win.h"
6 6
7 #include <ks.h> 7 #include <ks.h>
8 #include <ksmedia.h> 8 #include <ksmedia.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
11 #include <list> 11 #include <list>
12 12
13 #include "base/command_line.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/sys_string_conversions.h" 13 #include "base/strings/sys_string_conversions.h"
16 #include "base/win/metro.h"
17 #include "base/win/scoped_co_mem.h" 14 #include "base/win/scoped_co_mem.h"
18 #include "base/win/scoped_variant.h" 15 #include "base/win/scoped_variant.h"
19 #include "base/win/windows_version.h"
20 #include "media/base/media_switches.h"
21 #include "media/video/capture/win/video_capture_device_mf_win.h" 16 #include "media/video/capture/win/video_capture_device_mf_win.h"
22 17
23 using base::win::ScopedCoMem; 18 using base::win::ScopedCoMem;
24 using base::win::ScopedComPtr;
25 using base::win::ScopedVariant; 19 using base::win::ScopedVariant;
26 20
27 namespace media { 21 namespace media {
28 namespace {
29 22
30 // Finds and creates a DirectShow Video Capture filter matching the device_name. 23 // Finds and creates a DirectShow Video Capture filter matching the device_name.
31 HRESULT GetDeviceFilter(const VideoCaptureDevice::Name& device_name, 24 // static
32 IBaseFilter** filter) { 25 HRESULT VideoCaptureDeviceWin::GetDeviceFilter(
26 const VideoCaptureDevice::Name& device_name,
27 IBaseFilter** filter) {
33 DCHECK(filter); 28 DCHECK(filter);
34 29
35 ScopedComPtr<ICreateDevEnum> dev_enum; 30 ScopedComPtr<ICreateDevEnum> dev_enum;
36 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, 31 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL,
37 CLSCTX_INPROC); 32 CLSCTX_INPROC);
38 if (FAILED(hr)) 33 if (FAILED(hr))
39 return hr; 34 return hr;
40 35
41 ScopedComPtr<IEnumMoniker> enum_moniker; 36 ScopedComPtr<IEnumMoniker> enum_moniker;
42 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, 37 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 } 75 }
81 76
82 *filter = capture_filter.Detach(); 77 *filter = capture_filter.Detach();
83 if (!*filter && SUCCEEDED(hr)) 78 if (!*filter && SUCCEEDED(hr))
84 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); 79 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
85 80
86 return hr; 81 return hr;
87 } 82 }
88 83
89 // Check if a Pin matches a category. 84 // Check if a Pin matches a category.
90 bool PinMatchesCategory(IPin* pin, REFGUID category) { 85 // static
86 bool VideoCaptureDeviceWin::PinMatchesCategory(IPin* pin, REFGUID category) {
91 DCHECK(pin); 87 DCHECK(pin);
92 bool found = false; 88 bool found = false;
93 ScopedComPtr<IKsPropertySet> ks_property; 89 ScopedComPtr<IKsPropertySet> ks_property;
94 HRESULT hr = ks_property.QueryFrom(pin); 90 HRESULT hr = ks_property.QueryFrom(pin);
95 if (SUCCEEDED(hr)) { 91 if (SUCCEEDED(hr)) {
96 GUID pin_category; 92 GUID pin_category;
97 DWORD return_value; 93 DWORD return_value;
98 hr = ks_property->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0, 94 hr = ks_property->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0,
99 &pin_category, sizeof(pin_category), &return_value); 95 &pin_category, sizeof(pin_category), &return_value);
100 if (SUCCEEDED(hr) && (return_value == sizeof(pin_category))) { 96 if (SUCCEEDED(hr) && (return_value == sizeof(pin_category))) {
101 found = (pin_category == category); 97 found = (pin_category == category);
102 } 98 }
103 } 99 }
104 return found; 100 return found;
105 } 101 }
106 102
107 // Finds a IPin on a IBaseFilter given the direction an category. 103 // Finds a IPin on a IBaseFilter given the direction an category.
108 ScopedComPtr<IPin> GetPin(IBaseFilter* filter, PIN_DIRECTION pin_dir, 104 // static
109 REFGUID category) { 105 ScopedComPtr<IPin> VideoCaptureDeviceWin::GetPin(IBaseFilter* filter,
106 PIN_DIRECTION pin_dir,
107 REFGUID category) {
110 ScopedComPtr<IPin> pin; 108 ScopedComPtr<IPin> pin;
111 ScopedComPtr<IEnumPins> pin_emum; 109 ScopedComPtr<IEnumPins> pin_emum;
112 HRESULT hr = filter->EnumPins(pin_emum.Receive()); 110 HRESULT hr = filter->EnumPins(pin_emum.Receive());
113 if (pin_emum == NULL) 111 if (pin_emum == NULL)
114 return pin; 112 return pin;
115 113
116 // Get first unconnected pin. 114 // Get first unconnected pin.
117 hr = pin_emum->Reset(); // set to first pin 115 hr = pin_emum->Reset(); // set to first pin
118 while ((hr = pin_emum->Next(1, pin.Receive(), NULL)) == S_OK) { 116 while ((hr = pin_emum->Next(1, pin.Receive(), NULL)) == S_OK) {
119 PIN_DIRECTION this_pin_dir = static_cast<PIN_DIRECTION>(-1); 117 PIN_DIRECTION this_pin_dir = static_cast<PIN_DIRECTION>(-1);
120 hr = pin->QueryDirection(&this_pin_dir); 118 hr = pin->QueryDirection(&this_pin_dir);
121 if (pin_dir == this_pin_dir) { 119 if (pin_dir == this_pin_dir) {
122 if (category == GUID_NULL || PinMatchesCategory(pin, category)) 120 if (category == GUID_NULL || PinMatchesCategory(pin, category))
123 return pin; 121 return pin;
124 } 122 }
125 pin.Release(); 123 pin.Release();
126 } 124 }
127 125
128 DCHECK(!pin); 126 DCHECK(!pin);
129 return pin; 127 return pin;
130 } 128 }
131 129
132 // Release the format block for a media type. 130 // static
133 // http://msdn.microsoft.com/en-us/library/dd375432(VS.85).aspx 131 VideoPixelFormat VideoCaptureDeviceWin::TranslateMediaSubtypeToPixelFormat(
134 void FreeMediaType(AM_MEDIA_TYPE* mt) { 132 const GUID& sub_type) {
135 if (mt->cbFormat != 0) {
136 CoTaskMemFree(mt->pbFormat);
137 mt->cbFormat = 0;
138 mt->pbFormat = NULL;
139 }
140 if (mt->pUnk != NULL) {
141 NOTREACHED();
142 // pUnk should not be used.
143 mt->pUnk->Release();
144 mt->pUnk = NULL;
145 }
146 }
147
148 // Delete a media type structure that was allocated on the heap.
149 // http://msdn.microsoft.com/en-us/library/dd375432(VS.85).aspx
150 void DeleteMediaType(AM_MEDIA_TYPE* mt) {
151 if (mt != NULL) {
152 FreeMediaType(mt);
153 CoTaskMemFree(mt);
154 }
155 }
156
157 // A utility class that wraps the AM_MEDIA_TYPE type and guarantees that
158 // we free the structure when exiting the scope. DCHECKing is also done to
159 // avoid memory leaks.
160 class ScopedMediaType {
161 public:
162 ScopedMediaType() : media_type_(NULL) {}
163 ~ScopedMediaType() { Free(); }
164
165 AM_MEDIA_TYPE* operator->() { return media_type_; }
166 AM_MEDIA_TYPE* get() { return media_type_; }
167
168 void Free() {
169 if (!media_type_)
170 return;
171
172 DeleteMediaType(media_type_);
173 media_type_= NULL;
174 }
175
176 AM_MEDIA_TYPE** Receive() {
177 DCHECK(!media_type_);
178 return &media_type_;
179 }
180
181 private:
182 AM_MEDIA_TYPE* media_type_;
183 };
184
185 VideoPixelFormat TranslateMediaSubtypeToPixelFormat(const GUID& sub_type) {
186 static struct { 133 static struct {
187 const GUID& sub_type; 134 const GUID& sub_type;
188 VideoPixelFormat format; 135 VideoPixelFormat format;
189 } pixel_formats[] = { 136 } pixel_formats[] = {
190 { kMediaSubTypeI420, PIXEL_FORMAT_I420 }, 137 { kMediaSubTypeI420, PIXEL_FORMAT_I420 },
191 { MEDIASUBTYPE_IYUV, PIXEL_FORMAT_I420 }, 138 { MEDIASUBTYPE_IYUV, PIXEL_FORMAT_I420 },
192 { MEDIASUBTYPE_RGB24, PIXEL_FORMAT_RGB24 }, 139 { MEDIASUBTYPE_RGB24, PIXEL_FORMAT_RGB24 },
193 { MEDIASUBTYPE_YUY2, PIXEL_FORMAT_YUY2 }, 140 { MEDIASUBTYPE_YUY2, PIXEL_FORMAT_YUY2 },
194 { MEDIASUBTYPE_MJPG, PIXEL_FORMAT_MJPEG }, 141 { MEDIASUBTYPE_MJPG, PIXEL_FORMAT_MJPEG },
195 { MEDIASUBTYPE_UYVY, PIXEL_FORMAT_UYVY }, 142 { MEDIASUBTYPE_UYVY, PIXEL_FORMAT_UYVY },
196 { MEDIASUBTYPE_ARGB32, PIXEL_FORMAT_ARGB }, 143 { MEDIASUBTYPE_ARGB32, PIXEL_FORMAT_ARGB },
197 }; 144 };
198 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(pixel_formats); ++i) { 145 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(pixel_formats); ++i) {
199 if (sub_type == pixel_formats[i].sub_type) 146 if (sub_type == pixel_formats[i].sub_type)
200 return pixel_formats[i].format; 147 return pixel_formats[i].format;
201 } 148 }
202 #ifndef NDEBUG 149 #ifndef NDEBUG
203 WCHAR guid_str[128]; 150 WCHAR guid_str[128];
204 StringFromGUID2(sub_type, guid_str, arraysize(guid_str)); 151 StringFromGUID2(sub_type, guid_str, arraysize(guid_str));
205 DVLOG(2) << "Device (also) supports an unknown media type " << guid_str; 152 DVLOG(2) << "Device (also) supports an unknown media type " << guid_str;
206 #endif 153 #endif
207 return PIXEL_FORMAT_UNKNOWN; 154 return PIXEL_FORMAT_UNKNOWN;
208 } 155 }
209 156
210 } // namespace 157 void VideoCaptureDeviceWin::ScopedMediaType::Free() {
158 if (!media_type_)
159 return;
160
161 DeleteMediaType(media_type_);
162 media_type_= NULL;
163 }
164
165 AM_MEDIA_TYPE** VideoCaptureDeviceWin::ScopedMediaType::Receive() {
166 DCHECK(!media_type_);
167 return &media_type_;
168 }
169
170 // Release the format block for a media type.
171 // http://msdn.microsoft.com/en-us/library/dd375432(VS.85).aspx
172 void VideoCaptureDeviceWin::ScopedMediaType::FreeMediaType(AM_MEDIA_TYPE* mt) {
173 if (mt->cbFormat != 0) {
174 CoTaskMemFree(mt->pbFormat);
175 mt->cbFormat = 0;
176 mt->pbFormat = NULL;
177 }
178 if (mt->pUnk != NULL) {
179 NOTREACHED();
180 // pUnk should not be used.
181 mt->pUnk->Release();
182 mt->pUnk = NULL;
183 }
184 }
185
186 // Delete a media type structure that was allocated on the heap.
187 // http://msdn.microsoft.com/en-us/library/dd375432(VS.85).aspx
188 void VideoCaptureDeviceWin::ScopedMediaType::DeleteMediaType(
189 AM_MEDIA_TYPE* mt) {
190 if (mt != NULL) {
191 FreeMediaType(mt);
192 CoTaskMemFree(mt);
193 }
194 }
211 195
212 // static 196 // static
213 void VideoCaptureDevice::GetDeviceNames(Names* device_names) { 197 void VideoCaptureDevice::GetDeviceNames(Names* device_names) {
214 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 198 NOTIMPLEMENTED();
tommi (sloooow) - chröme 2014/05/15 15:18:33 not implemented? am I perhaps looking at a strang
mcasas 2014/05/15 16:03:23 It's missing a comment (like in Mac/Linux/Win). V
tommi (sloooow) - chröme 2014/05/19 10:51:37 Can we #ifdef this so that it's clear on what plat
mcasas 2014/05/19 12:59:50 Discussed offline.
215 // Use Media Foundation for Metro processes (after and including Win8) and
216 // DirectShow for any other versions, unless forced via flag. Media Foundation
217 // can also be forced if appropriate flag is set and we are in Windows 7 or
218 // 8 in non-Metro mode.
219 if ((base::win::IsMetroProcess() &&
220 !cmd_line->HasSwitch(switches::kForceDirectShowVideoCapture)) ||
221 (base::win::GetVersion() >= base::win::VERSION_WIN7 &&
222 cmd_line->HasSwitch(switches::kForceMediaFoundationVideoCapture))) {
223 VideoCaptureDeviceMFWin::GetDeviceNames(device_names);
224 } else {
225 VideoCaptureDeviceWin::GetDeviceNames(device_names);
226 }
227 } 199 }
228 200
229 // static 201 // static
230 void VideoCaptureDevice::GetDeviceSupportedFormats(const Name& device, 202 void VideoCaptureDevice::GetDeviceSupportedFormats(const Name& device,
231 VideoCaptureFormats* formats) { 203 VideoCaptureFormats* formats) {
232 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 204 NOTIMPLEMENTED();
tommi (sloooow) - chröme 2014/05/15 15:18:33 same here... I'm a bit confused (same for Create b
mcasas 2014/05/15 16:03:23 Done.
233 // Use Media Foundation for Metro processes (after and including Win8) and
234 // DirectShow for any other versions, unless forced via flag. Media Foundation
235 // can also be forced if appropriate flag is set and we are in Windows 7 or
236 // 8 in non-Metro mode.
237 if ((base::win::IsMetroProcess() &&
238 !cmd_line->HasSwitch(switches::kForceDirectShowVideoCapture)) ||
239 (base::win::GetVersion() >= base::win::VERSION_WIN7 &&
240 cmd_line->HasSwitch(switches::kForceMediaFoundationVideoCapture))) {
241 VideoCaptureDeviceMFWin::GetDeviceSupportedFormats(device, formats);
242 } else {
243 VideoCaptureDeviceWin::GetDeviceSupportedFormats(device, formats);
244 }
245 } 205 }
246 206
247 // static 207 // static
248 VideoCaptureDevice* VideoCaptureDevice::Create(const Name& device_name) { 208 VideoCaptureDevice* VideoCaptureDevice::Create(const Name& device_name) {
249 VideoCaptureDevice* ret = NULL; 209 NOTIMPLEMENTED();
250 if (device_name.capture_api_type() == Name::MEDIA_FOUNDATION) { 210 return NULL;
251 DCHECK(VideoCaptureDeviceMFWin::PlatformSupported());
252 scoped_ptr<VideoCaptureDeviceMFWin> device(
253 new VideoCaptureDeviceMFWin(device_name));
254 DVLOG(1) << " MediaFoundation Device: " << device_name.name();
255 if (device->Init())
256 ret = device.release();
257 } else if (device_name.capture_api_type() == Name::DIRECT_SHOW) {
258 scoped_ptr<VideoCaptureDeviceWin> device(
259 new VideoCaptureDeviceWin(device_name));
260 DVLOG(1) << " DirectShow Device: " << device_name.name();
261 if (device->Init())
262 ret = device.release();
263 } else{
264 NOTREACHED() << " Couldn't recognize VideoCaptureDevice type";
265 }
266
267 return ret;
268 }
269
270 // static
271 void VideoCaptureDeviceWin::GetDeviceNames(Names* device_names) {
272 DCHECK(device_names);
273
274 ScopedComPtr<ICreateDevEnum> dev_enum;
275 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL,
276 CLSCTX_INPROC);
277 if (FAILED(hr))
278 return;
279
280 ScopedComPtr<IEnumMoniker> enum_moniker;
281 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
282 enum_moniker.Receive(), 0);
283 // CreateClassEnumerator returns S_FALSE on some Windows OS
284 // when no camera exist. Therefore the FAILED macro can't be used.
285 if (hr != S_OK)
286 return;
287
288 device_names->clear();
289
290 // Name of a fake DirectShow filter that exist on computers with
291 // GTalk installed.
292 static const char kGoogleCameraAdapter[] = "google camera adapter";
293
294 // Enumerate all video capture devices.
295 ScopedComPtr<IMoniker> moniker;
296 int index = 0;
297 while (enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK) {
298 ScopedComPtr<IPropertyBag> prop_bag;
299 hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid());
300 if (FAILED(hr)) {
301 moniker.Release();
302 continue;
303 }
304
305 // Find the description or friendly name.
306 ScopedVariant name;
307 hr = prop_bag->Read(L"Description", name.Receive(), 0);
308 if (FAILED(hr))
309 hr = prop_bag->Read(L"FriendlyName", name.Receive(), 0);
310
311 if (SUCCEEDED(hr) && name.type() == VT_BSTR) {
312 // Ignore all VFW drivers and the special Google Camera Adapter.
313 // Google Camera Adapter is not a real DirectShow camera device.
314 // VFW are very old Video for Windows drivers that can not be used.
315 const wchar_t* str_ptr = V_BSTR(&name);
316 const int name_length = arraysize(kGoogleCameraAdapter) - 1;
317
318 if ((wcsstr(str_ptr, L"(VFW)") == NULL) &&
319 lstrlenW(str_ptr) < name_length ||
320 (!(LowerCaseEqualsASCII(str_ptr, str_ptr + name_length,
321 kGoogleCameraAdapter)))) {
322 std::string id;
323 std::string device_name(base::SysWideToUTF8(str_ptr));
324 name.Reset();
325 hr = prop_bag->Read(L"DevicePath", name.Receive(), 0);
326 if (FAILED(hr) || name.type() != VT_BSTR) {
327 id = device_name;
328 } else {
329 DCHECK_EQ(name.type(), VT_BSTR);
330 id = base::SysWideToUTF8(V_BSTR(&name));
331 }
332
333 device_names->push_back(Name(device_name, id, Name::DIRECT_SHOW));
334 }
335 }
336 moniker.Release();
337 }
338 }
339
340 // static
341 void VideoCaptureDeviceWin::GetDeviceSupportedFormats(const Name& device,
342 VideoCaptureFormats* formats) {
343 DVLOG(1) << "GetDeviceSupportedFormats for " << device.name();
344 ScopedComPtr<ICreateDevEnum> dev_enum;
345 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL,
346 CLSCTX_INPROC);
347 if (FAILED(hr))
348 return;
349
350 ScopedComPtr<IEnumMoniker> enum_moniker;
351 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
352 enum_moniker.Receive(), 0);
353 // CreateClassEnumerator returns S_FALSE on some Windows OS when no camera
354 // exists. Therefore the FAILED macro can't be used.
355 if (hr != S_OK)
356 return;
357
358 // Walk the capture devices. No need to check for "google camera adapter",
359 // since this is already skipped in the enumeration of GetDeviceNames().
360 ScopedComPtr<IMoniker> moniker;
361 int index = 0;
362 ScopedVariant device_id;
363 while (enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK) {
364 ScopedComPtr<IPropertyBag> prop_bag;
365 hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid());
366 if (FAILED(hr)) {
367 moniker.Release();
368 continue;
369 }
370
371 device_id.Reset();
372 hr = prop_bag->Read(L"DevicePath", device_id.Receive(), 0);
373 if (FAILED(hr)) {
374 DVLOG(1) << "Couldn't read a device's DevicePath.";
375 return;
376 }
377 if (device.id() == base::SysWideToUTF8(V_BSTR(&device_id)))
378 break;
379 moniker.Release();
380 }
381
382 if (moniker.get()) {
383 base::win::ScopedComPtr<IBaseFilter> capture_filter;
384 hr = GetDeviceFilter(device, capture_filter.Receive());
385 if (!capture_filter) {
386 DVLOG(2) << "Failed to create capture filter.";
387 return;
388 }
389
390 base::win::ScopedComPtr<IPin> output_capture_pin(
391 GetPin(capture_filter, PINDIR_OUTPUT, PIN_CATEGORY_CAPTURE));
392 if (!output_capture_pin) {
393 DVLOG(2) << "Failed to get capture output pin";
394 return;
395 }
396
397 ScopedComPtr<IAMStreamConfig> stream_config;
398 hr = output_capture_pin.QueryInterface(stream_config.Receive());
399 if (FAILED(hr)) {
400 DVLOG(2) << "Failed to get IAMStreamConfig interface from "
401 "capture device";
402 return;
403 }
404
405 int count = 0, size = 0;
406 hr = stream_config->GetNumberOfCapabilities(&count, &size);
407 if (FAILED(hr)) {
408 DVLOG(2) << "Failed to GetNumberOfCapabilities";
409 return;
410 }
411
412 scoped_ptr<BYTE[]> caps(new BYTE[size]);
413 for (int i = 0; i < count; ++i) {
414 ScopedMediaType media_type;
415 hr = stream_config->GetStreamCaps(i, media_type.Receive(), caps.get());
416 // GetStreamCaps() may return S_FALSE, so don't use FAILED() or SUCCEED()
417 // macros here since they'll trigger incorrectly.
418 if (hr != S_OK) {
419 DVLOG(2) << "Failed to GetStreamCaps";
420 return;
421 }
422
423 if (media_type->majortype == MEDIATYPE_Video &&
424 media_type->formattype == FORMAT_VideoInfo) {
425 VideoCaptureFormat format;
426 format.pixel_format =
427 TranslateMediaSubtypeToPixelFormat(media_type->subtype);
428 if (format.pixel_format == PIXEL_FORMAT_UNKNOWN)
429 continue;
430 VIDEOINFOHEADER* h =
431 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat);
432 format.frame_size.SetSize(h->bmiHeader.biWidth,
433 h->bmiHeader.biHeight);
434 // Trust the frame rate from the VIDEOINFOHEADER.
435 format.frame_rate = (h->AvgTimePerFrame > 0) ?
436 static_cast<int>(kSecondsToReferenceTime / h->AvgTimePerFrame) :
437 0;
438 formats->push_back(format);
439 DVLOG(1) << device.name() << " resolution: "
440 << format.frame_size.ToString() << ", fps: " << format.frame_rate
441 << ", pixel format: " << format.pixel_format;
442 }
443 }
444 }
445 } 211 }
446 212
447 VideoCaptureDeviceWin::VideoCaptureDeviceWin(const Name& device_name) 213 VideoCaptureDeviceWin::VideoCaptureDeviceWin(const Name& device_name)
448 : device_name_(device_name), 214 : device_name_(device_name),
449 state_(kIdle) { 215 state_(kIdle) {
450 DetachFromThread(); 216 DetachFromThread();
451 } 217 }
452 218
453 VideoCaptureDeviceWin::~VideoCaptureDeviceWin() { 219 VideoCaptureDeviceWin::~VideoCaptureDeviceWin() {
454 DCHECK(CalledOnValidThread()); 220 DCHECK(CalledOnValidThread());
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 } 555 }
790 } 556 }
791 557
792 void VideoCaptureDeviceWin::SetErrorState(const std::string& reason) { 558 void VideoCaptureDeviceWin::SetErrorState(const std::string& reason) {
793 DCHECK(CalledOnValidThread()); 559 DCHECK(CalledOnValidThread());
794 DVLOG(1) << reason; 560 DVLOG(1) << reason;
795 state_ = kError; 561 state_ = kError;
796 client_->OnError(reason); 562 client_->OnError(reason);
797 } 563 }
798 } // namespace media 564 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698