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

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: Rebased factory win. 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
« no previous file with comments | « media/video/capture/win/video_capture_device_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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; 19 using base::win::ScopedComPtr;
25 using base::win::ScopedVariant; 20 using base::win::ScopedVariant;
26 21
27 namespace media { 22 namespace media {
28 namespace {
29 23
30 // Finds and creates a DirectShow Video Capture filter matching the device_name. 24 // Finds and creates a DirectShow Video Capture filter matching the device_name.
31 HRESULT GetDeviceFilter(const VideoCaptureDevice::Name& device_name, 25 // static
32 IBaseFilter** filter) { 26 HRESULT VideoCaptureDeviceWin::GetDeviceFilter(
27 const VideoCaptureDevice::Name& device_name,
28 IBaseFilter** filter) {
33 DCHECK(filter); 29 DCHECK(filter);
34 30
35 ScopedComPtr<ICreateDevEnum> dev_enum; 31 ScopedComPtr<ICreateDevEnum> dev_enum;
36 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL, 32 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL,
37 CLSCTX_INPROC); 33 CLSCTX_INPROC);
38 if (FAILED(hr)) 34 if (FAILED(hr))
39 return hr; 35 return hr;
40 36
41 ScopedComPtr<IEnumMoniker> enum_moniker; 37 ScopedComPtr<IEnumMoniker> enum_moniker;
42 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, 38 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 } 76 }
81 77
82 *filter = capture_filter.Detach(); 78 *filter = capture_filter.Detach();
83 if (!*filter && SUCCEEDED(hr)) 79 if (!*filter && SUCCEEDED(hr))
84 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); 80 hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
85 81
86 return hr; 82 return hr;
87 } 83 }
88 84
89 // Check if a Pin matches a category. 85 // Check if a Pin matches a category.
90 bool PinMatchesCategory(IPin* pin, REFGUID category) { 86 // static
87 bool VideoCaptureDeviceWin::PinMatchesCategory(IPin* pin, REFGUID category) {
91 DCHECK(pin); 88 DCHECK(pin);
92 bool found = false; 89 bool found = false;
93 ScopedComPtr<IKsPropertySet> ks_property; 90 ScopedComPtr<IKsPropertySet> ks_property;
94 HRESULT hr = ks_property.QueryFrom(pin); 91 HRESULT hr = ks_property.QueryFrom(pin);
95 if (SUCCEEDED(hr)) { 92 if (SUCCEEDED(hr)) {
96 GUID pin_category; 93 GUID pin_category;
97 DWORD return_value; 94 DWORD return_value;
98 hr = ks_property->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0, 95 hr = ks_property->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0,
99 &pin_category, sizeof(pin_category), &return_value); 96 &pin_category, sizeof(pin_category), &return_value);
100 if (SUCCEEDED(hr) && (return_value == sizeof(pin_category))) { 97 if (SUCCEEDED(hr) && (return_value == sizeof(pin_category))) {
101 found = (pin_category == category); 98 found = (pin_category == category);
102 } 99 }
103 } 100 }
104 return found; 101 return found;
105 } 102 }
106 103
107 // Finds a IPin on a IBaseFilter given the direction an category. 104 // Finds a IPin on a IBaseFilter given the direction an category.
108 ScopedComPtr<IPin> GetPin(IBaseFilter* filter, PIN_DIRECTION pin_dir, 105 // static
109 REFGUID category) { 106 ScopedComPtr<IPin> VideoCaptureDeviceWin::GetPin(IBaseFilter* filter,
107 PIN_DIRECTION pin_dir,
108 REFGUID category) {
110 ScopedComPtr<IPin> pin; 109 ScopedComPtr<IPin> pin;
111 ScopedComPtr<IEnumPins> pin_emum; 110 ScopedComPtr<IEnumPins> pin_emum;
112 HRESULT hr = filter->EnumPins(pin_emum.Receive()); 111 HRESULT hr = filter->EnumPins(pin_emum.Receive());
113 if (pin_emum == NULL) 112 if (pin_emum == NULL)
114 return pin; 113 return pin;
115 114
116 // Get first unconnected pin. 115 // Get first unconnected pin.
117 hr = pin_emum->Reset(); // set to first pin 116 hr = pin_emum->Reset(); // set to first pin
118 while ((hr = pin_emum->Next(1, pin.Receive(), NULL)) == S_OK) { 117 while ((hr = pin_emum->Next(1, pin.Receive(), NULL)) == S_OK) {
119 PIN_DIRECTION this_pin_dir = static_cast<PIN_DIRECTION>(-1); 118 PIN_DIRECTION this_pin_dir = static_cast<PIN_DIRECTION>(-1);
120 hr = pin->QueryDirection(&this_pin_dir); 119 hr = pin->QueryDirection(&this_pin_dir);
121 if (pin_dir == this_pin_dir) { 120 if (pin_dir == this_pin_dir) {
122 if (category == GUID_NULL || PinMatchesCategory(pin, category)) 121 if (category == GUID_NULL || PinMatchesCategory(pin, category))
123 return pin; 122 return pin;
124 } 123 }
125 pin.Release(); 124 pin.Release();
126 } 125 }
127 126
128 DCHECK(!pin); 127 DCHECK(!pin);
129 return pin; 128 return pin;
130 } 129 }
131 130
132 // Release the format block for a media type. 131 // static
133 // http://msdn.microsoft.com/en-us/library/dd375432(VS.85).aspx 132 VideoPixelFormat VideoCaptureDeviceWin::TranslateMediaSubtypeToPixelFormat(
134 void FreeMediaType(AM_MEDIA_TYPE* mt) { 133 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 { 134 static struct {
187 const GUID& sub_type; 135 const GUID& sub_type;
188 VideoPixelFormat format; 136 VideoPixelFormat format;
189 } pixel_formats[] = { 137 } pixel_formats[] = {
190 { kMediaSubTypeI420, PIXEL_FORMAT_I420 }, 138 { kMediaSubTypeI420, PIXEL_FORMAT_I420 },
191 { MEDIASUBTYPE_IYUV, PIXEL_FORMAT_I420 }, 139 { MEDIASUBTYPE_IYUV, PIXEL_FORMAT_I420 },
192 { MEDIASUBTYPE_RGB24, PIXEL_FORMAT_RGB24 }, 140 { MEDIASUBTYPE_RGB24, PIXEL_FORMAT_RGB24 },
193 { MEDIASUBTYPE_YUY2, PIXEL_FORMAT_YUY2 }, 141 { MEDIASUBTYPE_YUY2, PIXEL_FORMAT_YUY2 },
194 { MEDIASUBTYPE_MJPG, PIXEL_FORMAT_MJPEG }, 142 { MEDIASUBTYPE_MJPG, PIXEL_FORMAT_MJPEG },
195 { MEDIASUBTYPE_UYVY, PIXEL_FORMAT_UYVY }, 143 { MEDIASUBTYPE_UYVY, PIXEL_FORMAT_UYVY },
196 { MEDIASUBTYPE_ARGB32, PIXEL_FORMAT_ARGB }, 144 { MEDIASUBTYPE_ARGB32, PIXEL_FORMAT_ARGB },
197 }; 145 };
198 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(pixel_formats); ++i) { 146 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(pixel_formats); ++i) {
199 if (sub_type == pixel_formats[i].sub_type) 147 if (sub_type == pixel_formats[i].sub_type)
200 return pixel_formats[i].format; 148 return pixel_formats[i].format;
201 } 149 }
202 #ifndef NDEBUG 150 #ifndef NDEBUG
203 WCHAR guid_str[128]; 151 WCHAR guid_str[128];
204 StringFromGUID2(sub_type, guid_str, arraysize(guid_str)); 152 StringFromGUID2(sub_type, guid_str, arraysize(guid_str));
205 DVLOG(2) << "Device (also) supports an unknown media type " << guid_str; 153 DVLOG(2) << "Device (also) supports an unknown media type " << guid_str;
206 #endif 154 #endif
207 return PIXEL_FORMAT_UNKNOWN; 155 return PIXEL_FORMAT_UNKNOWN;
208 } 156 }
209 157
210 } // namespace 158 void VideoCaptureDeviceWin::ScopedMediaType::Free() {
159 if (!media_type_)
160 return;
211 161
162 DeleteMediaType(media_type_);
163 media_type_= NULL;
164 }
165
166 AM_MEDIA_TYPE** VideoCaptureDeviceWin::ScopedMediaType::Receive() {
167 DCHECK(!media_type_);
168 return &media_type_;
169 }
170
171 // Release the format block for a media type.
172 // http://msdn.microsoft.com/en-us/library/dd375432(VS.85).aspx
173 void VideoCaptureDeviceWin::ScopedMediaType::FreeMediaType(AM_MEDIA_TYPE* mt) {
174 if (mt->cbFormat != 0) {
175 CoTaskMemFree(mt->pbFormat);
176 mt->cbFormat = 0;
177 mt->pbFormat = NULL;
178 }
179 if (mt->pUnk != NULL) {
180 NOTREACHED();
181 // pUnk should not be used.
182 mt->pUnk->Release();
183 mt->pUnk = NULL;
184 }
185 }
186
187 // Delete a media type structure that was allocated on the heap.
188 // http://msdn.microsoft.com/en-us/library/dd375432(VS.85).aspx
189 void VideoCaptureDeviceWin::ScopedMediaType::DeleteMediaType(
190 AM_MEDIA_TYPE* mt) {
191 if (mt != NULL) {
192 FreeMediaType(mt);
193 CoTaskMemFree(mt);
194 }
195 }
196
197 // TODO(mcasas): Remove the following static methods when they are no longer
198 // referenced from VideoCaptureDeviceFactory, i.e. when all OS platforms have
199 // splitted the VideoCaptureDevice into VideoCaptureDevice and
200 // VideoCaptureDeviceFactory.
212 // static 201 // static
213 void VideoCaptureDevice::GetDeviceNames(Names* device_names) { 202 void VideoCaptureDevice::GetDeviceNames(Names* device_names) {
214 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 203 NOTIMPLEMENTED();
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 } 204 }
228 205
229 // static 206 // static
230 void VideoCaptureDevice::GetDeviceSupportedFormats(const Name& device, 207 void VideoCaptureDevice::GetDeviceSupportedFormats(const Name& device,
231 VideoCaptureFormats* formats) { 208 VideoCaptureFormats* formats) {
232 const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 209 NOTIMPLEMENTED();
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 } 210 }
246 211
247 // static 212 // static
248 VideoCaptureDevice* VideoCaptureDevice::Create( 213 VideoCaptureDevice* VideoCaptureDevice::Create(
249 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner, 214 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
250 const Name& device_name) { 215 const Name& device_name) {
251 VideoCaptureDevice* ret = NULL; 216 NOTIMPLEMENTED();
252 if (device_name.capture_api_type() == Name::MEDIA_FOUNDATION) { 217 return NULL;
253 DCHECK(VideoCaptureDeviceMFWin::PlatformSupported());
254 scoped_ptr<VideoCaptureDeviceMFWin> device(
255 new VideoCaptureDeviceMFWin(device_name));
256 DVLOG(1) << " MediaFoundation Device: " << device_name.name();
257 if (device->Init())
258 ret = device.release();
259 } else if (device_name.capture_api_type() == Name::DIRECT_SHOW) {
260 scoped_ptr<VideoCaptureDeviceWin> device(
261 new VideoCaptureDeviceWin(device_name));
262 DVLOG(1) << " DirectShow Device: " << device_name.name();
263 if (device->Init())
264 ret = device.release();
265 } else{
266 NOTREACHED() << " Couldn't recognize VideoCaptureDevice type";
267 }
268
269 return ret;
270 }
271
272 // static
273 void VideoCaptureDeviceWin::GetDeviceNames(Names* device_names) {
274 DCHECK(device_names);
275
276 ScopedComPtr<ICreateDevEnum> dev_enum;
277 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL,
278 CLSCTX_INPROC);
279 if (FAILED(hr))
280 return;
281
282 ScopedComPtr<IEnumMoniker> enum_moniker;
283 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
284 enum_moniker.Receive(), 0);
285 // CreateClassEnumerator returns S_FALSE on some Windows OS
286 // when no camera exist. Therefore the FAILED macro can't be used.
287 if (hr != S_OK)
288 return;
289
290 device_names->clear();
291
292 // Name of a fake DirectShow filter that exist on computers with
293 // GTalk installed.
294 static const char kGoogleCameraAdapter[] = "google camera adapter";
295
296 // Enumerate all video capture devices.
297 ScopedComPtr<IMoniker> moniker;
298 int index = 0;
299 while (enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK) {
300 ScopedComPtr<IPropertyBag> prop_bag;
301 hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid());
302 if (FAILED(hr)) {
303 moniker.Release();
304 continue;
305 }
306
307 // Find the description or friendly name.
308 ScopedVariant name;
309 hr = prop_bag->Read(L"Description", name.Receive(), 0);
310 if (FAILED(hr))
311 hr = prop_bag->Read(L"FriendlyName", name.Receive(), 0);
312
313 if (SUCCEEDED(hr) && name.type() == VT_BSTR) {
314 // Ignore all VFW drivers and the special Google Camera Adapter.
315 // Google Camera Adapter is not a real DirectShow camera device.
316 // VFW are very old Video for Windows drivers that can not be used.
317 const wchar_t* str_ptr = V_BSTR(&name);
318 const int name_length = arraysize(kGoogleCameraAdapter) - 1;
319
320 if ((wcsstr(str_ptr, L"(VFW)") == NULL) &&
321 lstrlenW(str_ptr) < name_length ||
322 (!(LowerCaseEqualsASCII(str_ptr, str_ptr + name_length,
323 kGoogleCameraAdapter)))) {
324 std::string id;
325 std::string device_name(base::SysWideToUTF8(str_ptr));
326 name.Reset();
327 hr = prop_bag->Read(L"DevicePath", name.Receive(), 0);
328 if (FAILED(hr) || name.type() != VT_BSTR) {
329 id = device_name;
330 } else {
331 DCHECK_EQ(name.type(), VT_BSTR);
332 id = base::SysWideToUTF8(V_BSTR(&name));
333 }
334
335 device_names->push_back(Name(device_name, id, Name::DIRECT_SHOW));
336 }
337 }
338 moniker.Release();
339 }
340 }
341
342 // static
343 void VideoCaptureDeviceWin::GetDeviceSupportedFormats(const Name& device,
344 VideoCaptureFormats* formats) {
345 DVLOG(1) << "GetDeviceSupportedFormats for " << device.name();
346 ScopedComPtr<ICreateDevEnum> dev_enum;
347 HRESULT hr = dev_enum.CreateInstance(CLSID_SystemDeviceEnum, NULL,
348 CLSCTX_INPROC);
349 if (FAILED(hr))
350 return;
351
352 ScopedComPtr<IEnumMoniker> enum_moniker;
353 hr = dev_enum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
354 enum_moniker.Receive(), 0);
355 // CreateClassEnumerator returns S_FALSE on some Windows OS when no camera
356 // exists. Therefore the FAILED macro can't be used.
357 if (hr != S_OK)
358 return;
359
360 // Walk the capture devices. No need to check for "google camera adapter",
361 // since this is already skipped in the enumeration of GetDeviceNames().
362 ScopedComPtr<IMoniker> moniker;
363 int index = 0;
364 ScopedVariant device_id;
365 while (enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK) {
366 ScopedComPtr<IPropertyBag> prop_bag;
367 hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid());
368 if (FAILED(hr)) {
369 moniker.Release();
370 continue;
371 }
372
373 device_id.Reset();
374 hr = prop_bag->Read(L"DevicePath", device_id.Receive(), 0);
375 if (FAILED(hr)) {
376 DVLOG(1) << "Couldn't read a device's DevicePath.";
377 return;
378 }
379 if (device.id() == base::SysWideToUTF8(V_BSTR(&device_id)))
380 break;
381 moniker.Release();
382 }
383
384 if (moniker.get()) {
385 base::win::ScopedComPtr<IBaseFilter> capture_filter;
386 hr = GetDeviceFilter(device, capture_filter.Receive());
387 if (!capture_filter) {
388 DVLOG(2) << "Failed to create capture filter.";
389 return;
390 }
391
392 base::win::ScopedComPtr<IPin> output_capture_pin(
393 GetPin(capture_filter, PINDIR_OUTPUT, PIN_CATEGORY_CAPTURE));
394 if (!output_capture_pin) {
395 DVLOG(2) << "Failed to get capture output pin";
396 return;
397 }
398
399 ScopedComPtr<IAMStreamConfig> stream_config;
400 hr = output_capture_pin.QueryInterface(stream_config.Receive());
401 if (FAILED(hr)) {
402 DVLOG(2) << "Failed to get IAMStreamConfig interface from "
403 "capture device";
404 return;
405 }
406
407 int count = 0, size = 0;
408 hr = stream_config->GetNumberOfCapabilities(&count, &size);
409 if (FAILED(hr)) {
410 DVLOG(2) << "Failed to GetNumberOfCapabilities";
411 return;
412 }
413
414 scoped_ptr<BYTE[]> caps(new BYTE[size]);
415 for (int i = 0; i < count; ++i) {
416 ScopedMediaType media_type;
417 hr = stream_config->GetStreamCaps(i, media_type.Receive(), caps.get());
418 // GetStreamCaps() may return S_FALSE, so don't use FAILED() or SUCCEED()
419 // macros here since they'll trigger incorrectly.
420 if (hr != S_OK) {
421 DVLOG(2) << "Failed to GetStreamCaps";
422 return;
423 }
424
425 if (media_type->majortype == MEDIATYPE_Video &&
426 media_type->formattype == FORMAT_VideoInfo) {
427 VideoCaptureFormat format;
428 format.pixel_format =
429 TranslateMediaSubtypeToPixelFormat(media_type->subtype);
430 if (format.pixel_format == PIXEL_FORMAT_UNKNOWN)
431 continue;
432 VIDEOINFOHEADER* h =
433 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat);
434 format.frame_size.SetSize(h->bmiHeader.biWidth,
435 h->bmiHeader.biHeight);
436 // Trust the frame rate from the VIDEOINFOHEADER.
437 format.frame_rate = (h->AvgTimePerFrame > 0) ?
438 static_cast<int>(kSecondsToReferenceTime / h->AvgTimePerFrame) :
439 0;
440 formats->push_back(format);
441 DVLOG(1) << device.name() << " resolution: "
442 << format.frame_size.ToString() << ", fps: " << format.frame_rate
443 << ", pixel format: " << format.pixel_format;
444 }
445 }
446 }
447 } 218 }
448 219
449 VideoCaptureDeviceWin::VideoCaptureDeviceWin(const Name& device_name) 220 VideoCaptureDeviceWin::VideoCaptureDeviceWin(const Name& device_name)
450 : device_name_(device_name), 221 : device_name_(device_name),
451 state_(kIdle) { 222 state_(kIdle) {
452 DetachFromThread(); 223 DetachFromThread();
453 } 224 }
454 225
455 VideoCaptureDeviceWin::~VideoCaptureDeviceWin() { 226 VideoCaptureDeviceWin::~VideoCaptureDeviceWin() {
456 DCHECK(CalledOnValidThread()); 227 DCHECK(CalledOnValidThread());
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 } 562 }
792 } 563 }
793 564
794 void VideoCaptureDeviceWin::SetErrorState(const std::string& reason) { 565 void VideoCaptureDeviceWin::SetErrorState(const std::string& reason) {
795 DCHECK(CalledOnValidThread()); 566 DCHECK(CalledOnValidThread());
796 DVLOG(1) << reason; 567 DVLOG(1) << reason;
797 state_ = kError; 568 state_ = kError;
798 client_->OnError(reason); 569 client_->OnError(reason);
799 } 570 }
800 } // namespace media 571 } // namespace media
OLDNEW
« no previous file with comments | « media/video/capture/win/video_capture_device_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698