OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_factory_win.h" | 5 #include "media/video/capture/win/video_capture_device_factory_win.h" |
6 | 6 |
7 #include <mfapi.h> | 7 #include <mfapi.h> |
8 #include <mferror.h> | 8 #include <mferror.h> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 ScopedComPtr<IMoniker> moniker; | 116 ScopedComPtr<IMoniker> moniker; |
117 int index = 0; | 117 int index = 0; |
118 while (enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK) { | 118 while (enum_moniker->Next(1, moniker.Receive(), NULL) == S_OK) { |
119 ScopedComPtr<IPropertyBag> prop_bag; | 119 ScopedComPtr<IPropertyBag> prop_bag; |
120 hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid()); | 120 hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid()); |
121 if (FAILED(hr)) { | 121 if (FAILED(hr)) { |
122 moniker.Release(); | 122 moniker.Release(); |
123 continue; | 123 continue; |
124 } | 124 } |
125 | 125 |
126 // Find the description or friendly name. | 126 // Find the description or friendly name. TODO(mcasas): Investigate using |
| 127 // FriendlyName before Description, http://crbug.com/383395. |
127 ScopedVariant name; | 128 ScopedVariant name; |
128 hr = prop_bag->Read(L"Description", name.Receive(), 0); | 129 hr = prop_bag->Read(L"Description", name.Receive(), 0); |
129 if (FAILED(hr)) | 130 if (FAILED(hr)) |
130 hr = prop_bag->Read(L"FriendlyName", name.Receive(), 0); | 131 hr = prop_bag->Read(L"FriendlyName", name.Receive(), 0); |
131 | 132 |
132 if (SUCCEEDED(hr) && name.type() == VT_BSTR) { | 133 if (SUCCEEDED(hr) && name.type() == VT_BSTR) { |
133 // Ignore all VFW drivers and the special Google Camera Adapter. | 134 // Ignore all VFW drivers and the special Google Camera Adapter. |
134 // Google Camera Adapter is not a real DirectShow camera device. | 135 // Google Camera Adapter is not a real DirectShow camera device. |
135 // VFW are very old Video for Windows drivers that can not be used. | 136 // VFW are very old Video for Windows drivers that can not be used. |
136 const wchar_t* str_ptr = V_BSTR(&name); | 137 const wchar_t* str_ptr = V_BSTR(&name); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid()); | 217 hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, prop_bag.ReceiveVoid()); |
217 if (FAILED(hr)) { | 218 if (FAILED(hr)) { |
218 moniker.Release(); | 219 moniker.Release(); |
219 continue; | 220 continue; |
220 } | 221 } |
221 | 222 |
222 std::string id; | 223 std::string id; |
223 device_id.Reset(); | 224 device_id.Reset(); |
224 hr = prop_bag->Read(L"DevicePath", device_id.Receive(), 0); | 225 hr = prop_bag->Read(L"DevicePath", device_id.Receive(), 0); |
225 if (FAILED(hr) || device_id.type() != VT_BSTR) { | 226 if (FAILED(hr) || device_id.type() != VT_BSTR) { |
226 // If there is no clear DevicePath, try with Description and FriendlyName. | 227 // If there is no clear DevicePath, try with Description and FriendlyName, |
| 228 // this might happen with non-USB cameras such as DeckLinks. TODO(mcasas): |
| 229 // use FriendlyName before Description, http://crbug.com/383395. |
227 ScopedVariant name; | 230 ScopedVariant name; |
228 if (SUCCEEDED(prop_bag->Read(L"Description", name.Receive(), 0)) || | 231 if (SUCCEEDED(prop_bag->Read(L"Description", name.Receive(), 0)) || |
229 SUCCEEDED(prop_bag->Read(L"FriendlyName", name.Receive(), 0))) { | 232 SUCCEEDED(prop_bag->Read(L"FriendlyName", name.Receive(), 0))) { |
230 id = base::SysWideToUTF8(V_BSTR(&name)); | 233 id = base::SysWideToUTF8(V_BSTR(&name)); |
231 } | 234 } |
232 } else { | 235 } else { |
233 DCHECK_EQ(device_id.type(), VT_BSTR); | 236 DCHECK_EQ(device_id.type(), VT_BSTR); |
234 id = base::SysWideToUTF8(V_BSTR(&device_id)); | 237 id = base::SysWideToUTF8(V_BSTR(&device_id)); |
235 } | 238 } |
236 | 239 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 VideoCaptureDeviceWin::TranslateMediaSubtypeToPixelFormat( | 293 VideoCaptureDeviceWin::TranslateMediaSubtypeToPixelFormat( |
291 media_type->subtype); | 294 media_type->subtype); |
292 if (format.pixel_format == PIXEL_FORMAT_UNKNOWN) | 295 if (format.pixel_format == PIXEL_FORMAT_UNKNOWN) |
293 continue; | 296 continue; |
294 VIDEOINFOHEADER* h = | 297 VIDEOINFOHEADER* h = |
295 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); | 298 reinterpret_cast<VIDEOINFOHEADER*>(media_type->pbFormat); |
296 format.frame_size.SetSize(h->bmiHeader.biWidth, | 299 format.frame_size.SetSize(h->bmiHeader.biWidth, |
297 h->bmiHeader.biHeight); | 300 h->bmiHeader.biHeight); |
298 // Trust the frame rate from the VIDEOINFOHEADER. | 301 // Trust the frame rate from the VIDEOINFOHEADER. |
299 format.frame_rate = (h->AvgTimePerFrame > 0) ? | 302 format.frame_rate = (h->AvgTimePerFrame > 0) ? |
300 static_cast<int>(kSecondsToReferenceTime / h->AvgTimePerFrame) : | 303 kSecondsToReferenceTime / static_cast<float>(h->AvgTimePerFrame) : |
301 0; | 304 0.0; |
| 305 |
302 formats->push_back(format); | 306 formats->push_back(format); |
303 DVLOG(1) << device.name() << " resolution: " | 307 DVLOG(1) << device.name() << " resolution: " |
304 << format.frame_size.ToString() << ", fps: " << format.frame_rate | 308 << format.frame_size.ToString() << ", fps: " << format.frame_rate |
305 << ", pixel format: " << format.pixel_format; | 309 << ", pixel format: " << format.pixel_format; |
306 } | 310 } |
307 } | 311 } |
308 } | 312 } |
309 } | 313 } |
310 | 314 |
311 static void GetDeviceSupportedFormatsMediaFoundation( | 315 static void GetDeviceSupportedFormatsMediaFoundation( |
(...skipping 26 matching lines...) Expand all Loading... |
338 } | 342 } |
339 VideoCaptureFormat capture_format; | 343 VideoCaptureFormat capture_format; |
340 capture_format.frame_size.SetSize(width, height); | 344 capture_format.frame_size.SetSize(width, height); |
341 | 345 |
342 UINT32 numerator, denominator; | 346 UINT32 numerator, denominator; |
343 hr = MFGetAttributeRatio(type, MF_MT_FRAME_RATE, &numerator, &denominator); | 347 hr = MFGetAttributeRatio(type, MF_MT_FRAME_RATE, &numerator, &denominator); |
344 if (FAILED(hr)) { | 348 if (FAILED(hr)) { |
345 DLOG(ERROR) << "MFGetAttributeSize: " << std::hex << hr; | 349 DLOG(ERROR) << "MFGetAttributeSize: " << std::hex << hr; |
346 return; | 350 return; |
347 } | 351 } |
348 capture_format.frame_rate = denominator ? numerator / denominator : 0; | 352 capture_format.frame_rate = denominator ? |
| 353 numerator / static_cast<float>(denominator) : 0.0f; |
349 | 354 |
350 GUID type_guid; | 355 GUID type_guid; |
351 hr = type->GetGUID(MF_MT_SUBTYPE, &type_guid); | 356 hr = type->GetGUID(MF_MT_SUBTYPE, &type_guid); |
352 if (FAILED(hr)) { | 357 if (FAILED(hr)) { |
353 DLOG(ERROR) << "GetGUID: " << std::hex << hr; | 358 DLOG(ERROR) << "GetGUID: " << std::hex << hr; |
354 return; | 359 return; |
355 } | 360 } |
356 VideoCaptureDeviceMFWin::FormatFromGuid(type_guid, | 361 VideoCaptureDeviceMFWin::FormatFromGuid(type_guid, |
357 &capture_format.pixel_format); | 362 &capture_format.pixel_format); |
358 type.Release(); | 363 type.Release(); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 const VideoCaptureDevice::Name& device, | 441 const VideoCaptureDevice::Name& device, |
437 VideoCaptureFormats* formats) { | 442 VideoCaptureFormats* formats) { |
438 DCHECK(thread_checker_.CalledOnValidThread()); | 443 DCHECK(thread_checker_.CalledOnValidThread()); |
439 if (use_media_foundation_) | 444 if (use_media_foundation_) |
440 GetDeviceSupportedFormatsMediaFoundation(device, formats); | 445 GetDeviceSupportedFormatsMediaFoundation(device, formats); |
441 else | 446 else |
442 GetDeviceSupportedFormatsDirectShow(device, formats); | 447 GetDeviceSupportedFormatsDirectShow(device, formats); |
443 } | 448 } |
444 | 449 |
445 } // namespace media | 450 } // namespace media |
OLD | NEW |