OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 24 matching lines...) Expand all Loading... |
35 {176,144,101}, | 35 {176,144,101}, |
36 {160,120,109}, | 36 {160,120,109}, |
37 {1280,720,166}, | 37 {1280,720,166}, |
38 {960,544,126}, | 38 {960,544,126}, |
39 {800,448,120}, | 39 {800,448,120}, |
40 {800,600,127} | 40 {800,600,127} |
41 }, | 41 }, |
42 }; | 42 }; |
43 | 43 |
44 // static | 44 // static |
45 DeviceInfoDS* DeviceInfoDS::Create(const int32_t id) | 45 DeviceInfoDS* DeviceInfoDS::Create() |
46 { | 46 { |
47 DeviceInfoDS* dsInfo = new DeviceInfoDS(id); | 47 DeviceInfoDS* dsInfo = new DeviceInfoDS(); |
48 if (!dsInfo || dsInfo->Init() != 0) | 48 if (!dsInfo || dsInfo->Init() != 0) |
49 { | 49 { |
50 delete dsInfo; | 50 delete dsInfo; |
51 dsInfo = NULL; | 51 dsInfo = NULL; |
52 } | 52 } |
53 return dsInfo; | 53 return dsInfo; |
54 } | 54 } |
55 | 55 |
56 DeviceInfoDS::DeviceInfoDS(const int32_t id) | 56 DeviceInfoDS::DeviceInfoDS() |
57 : DeviceInfoImpl(id), _dsDevEnum(NULL), _dsMonikerDevEnum(NULL), | 57 : _dsDevEnum(NULL), _dsMonikerDevEnum(NULL), |
58 _CoUninitializeIsRequired(true) | 58 _CoUninitializeIsRequired(true) |
59 { | 59 { |
60 // 1) Initialize the COM library (make Windows load the DLLs). | 60 // 1) Initialize the COM library (make Windows load the DLLs). |
61 // | 61 // |
62 // CoInitializeEx must be called at least once, and is usually called only o
nce, | 62 // CoInitializeEx must be called at least once, and is usually called only o
nce, |
63 // for each thread that uses the COM library. Multiple calls to CoInitialize
Ex | 63 // for each thread that uses the COM library. Multiple calls to CoInitialize
Ex |
64 // by the same thread are allowed as long as they pass the same concurrency
flag, | 64 // by the same thread are allowed as long as they pass the same concurrency
flag, |
65 // but subsequent valid calls return S_FALSE. | 65 // but subsequent valid calls return S_FALSE. |
66 // To close the COM library gracefully on a thread, each successful call to | 66 // To close the COM library gracefully on a thread, each successful call to |
67 // CoInitializeEx, including any call that returns S_FALSE, must be balanced | 67 // CoInitializeEx, including any call that returns S_FALSE, must be balanced |
(...skipping 13 matching lines...) Expand all Loading... |
81 { | 81 { |
82 // Avoid calling CoUninitialize() since CoInitializeEx() failed. | 82 // Avoid calling CoUninitialize() since CoInitializeEx() failed. |
83 _CoUninitializeIsRequired = FALSE; | 83 _CoUninitializeIsRequired = FALSE; |
84 | 84 |
85 if (hr == RPC_E_CHANGED_MODE) | 85 if (hr == RPC_E_CHANGED_MODE) |
86 { | 86 { |
87 // Calling thread has already initialized COM to be used in a single
-threaded | 87 // Calling thread has already initialized COM to be used in a single
-threaded |
88 // apartment (STA). We are then prevented from using STA. | 88 // apartment (STA). We are then prevented from using STA. |
89 // Details: hr = 0x80010106 <=> "Cannot change thread mode after it
is set". | 89 // Details: hr = 0x80010106 <=> "Cannot change thread mode after it
is set". |
90 // | 90 // |
91 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id, | 91 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, 0, |
92 "VideoCaptureWindowsDSInfo::VideoCaptureWindowsDSInfo " | 92 "VideoCaptureWindowsDSInfo::VideoCaptureWindowsDSInfo " |
93 "CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) => " | 93 "CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) => " |
94 "RPC_E_CHANGED_MODE, error 0x%x", | 94 "RPC_E_CHANGED_MODE, error 0x%x", |
95 hr); | 95 hr); |
96 } | 96 } |
97 } | 97 } |
98 } | 98 } |
99 | 99 |
100 DeviceInfoDS::~DeviceInfoDS() | 100 DeviceInfoDS::~DeviceInfoDS() |
101 { | 101 { |
102 RELEASE_AND_CLEAR(_dsMonikerDevEnum); | 102 RELEASE_AND_CLEAR(_dsMonikerDevEnum); |
103 RELEASE_AND_CLEAR(_dsDevEnum); | 103 RELEASE_AND_CLEAR(_dsDevEnum); |
104 if (_CoUninitializeIsRequired) | 104 if (_CoUninitializeIsRequired) |
105 { | 105 { |
106 CoUninitialize(); | 106 CoUninitialize(); |
107 } | 107 } |
108 } | 108 } |
109 | 109 |
110 int32_t DeviceInfoDS::Init() | 110 int32_t DeviceInfoDS::Init() |
111 { | 111 { |
112 HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, | 112 HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, |
113 IID_ICreateDevEnum, (void **) &_dsDevEnum); | 113 IID_ICreateDevEnum, (void **) &_dsDevEnum); |
114 if (hr != NOERROR) | 114 if (hr != NOERROR) |
115 { | 115 { |
116 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 116 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
117 "Failed to create CLSID_SystemDeviceEnum, error 0x%x", hr); | 117 "Failed to create CLSID_SystemDeviceEnum, error 0x%x", hr); |
118 return -1; | 118 return -1; |
119 } | 119 } |
120 return 0; | 120 return 0; |
121 } | 121 } |
122 uint32_t DeviceInfoDS::NumberOfDevices() | 122 uint32_t DeviceInfoDS::NumberOfDevices() |
123 { | 123 { |
124 ReadLockScoped cs(_apiLock); | 124 ReadLockScoped cs(_apiLock); |
125 return GetDeviceInfo(0, 0, 0, 0, 0, 0, 0); | 125 return GetDeviceInfo(0, 0, 0, 0, 0, 0, 0); |
126 } | 126 } |
(...skipping 28 matching lines...) Expand all Loading... |
155 | 155 |
156 { | 156 { |
157 | 157 |
158 // enumerate all video capture devices | 158 // enumerate all video capture devices |
159 RELEASE_AND_CLEAR(_dsMonikerDevEnum); | 159 RELEASE_AND_CLEAR(_dsMonikerDevEnum); |
160 HRESULT hr = | 160 HRESULT hr = |
161 _dsDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, | 161 _dsDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, |
162 &_dsMonikerDevEnum, 0); | 162 &_dsMonikerDevEnum, 0); |
163 if (hr != NOERROR) | 163 if (hr != NOERROR) |
164 { | 164 { |
165 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 165 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
166 "Failed to enumerate CLSID_SystemDeviceEnum, error 0x%x." | 166 "Failed to enumerate CLSID_SystemDeviceEnum, error 0x%x." |
167 " No webcam exist?", hr); | 167 " No webcam exist?", hr); |
168 return 0; | 168 return 0; |
169 } | 169 } |
170 | 170 |
171 _dsMonikerDevEnum->Reset(); | 171 _dsMonikerDevEnum->Reset(); |
172 ULONG cFetched; | 172 ULONG cFetched; |
173 IMoniker *pM; | 173 IMoniker *pM; |
174 int index = 0; | 174 int index = 0; |
175 while (S_OK == _dsMonikerDevEnum->Next(1, &pM, &cFetched)) | 175 while (S_OK == _dsMonikerDevEnum->Next(1, &pM, &cFetched)) |
(...skipping 24 matching lines...) Expand all Loading... |
200 if (deviceNameLength > 0) | 200 if (deviceNameLength > 0) |
201 { | 201 { |
202 convResult = WideCharToMultiByte(CP_UTF8, 0, | 202 convResult = WideCharToMultiByte(CP_UTF8, 0, |
203 varName.bstrVal, -1
, | 203 varName.bstrVal, -1
, |
204 (char*) deviceNameU
TF8, | 204 (char*) deviceNameU
TF8, |
205 deviceNameLength, N
ULL, | 205 deviceNameLength, N
ULL, |
206 NULL); | 206 NULL); |
207 if (convResult == 0) | 207 if (convResult == 0) |
208 { | 208 { |
209 WEBRTC_TRACE(webrtc::kTraceError, | 209 WEBRTC_TRACE(webrtc::kTraceError, |
210 webrtc::kTraceVideoCapture, _id, | 210 webrtc::kTraceVideoCapture, 0, |
211 "Failed to convert device name to U
TF8. %d", | 211 "Failed to convert device name to U
TF8. %d", |
212 GetLastError()); | 212 GetLastError()); |
213 return -1; | 213 return -1; |
214 } | 214 } |
215 } | 215 } |
216 if (deviceUniqueIdUTF8Length > 0) | 216 if (deviceUniqueIdUTF8Length > 0) |
217 { | 217 { |
218 hr = pBag->Read(L"DevicePath", &varName, 0); | 218 hr = pBag->Read(L"DevicePath", &varName, 0); |
219 if (FAILED(hr)) | 219 if (FAILED(hr)) |
220 { | 220 { |
221 strncpy_s((char *) deviceUniqueIdUTF8, | 221 strncpy_s((char *) deviceUniqueIdUTF8, |
222 deviceUniqueIdUTF8Length, | 222 deviceUniqueIdUTF8Length, |
223 (char *) deviceNameUTF8, convResult); | 223 (char *) deviceNameUTF8, convResult); |
224 WEBRTC_TRACE(webrtc::kTraceError, | 224 WEBRTC_TRACE(webrtc::kTraceError, |
225 webrtc::kTraceVideoCapture, _id, | 225 webrtc::kTraceVideoCapture, 0, |
226 "Failed to get deviceUniqueIdUTF8 u
sing deviceNameUTF8"); | 226 "Failed to get deviceUniqueIdUTF8 u
sing deviceNameUTF8"); |
227 } | 227 } |
228 else | 228 else |
229 { | 229 { |
230 convResult = WideCharToMultiByte( | 230 convResult = WideCharToMultiByte( |
231 CP_UTF8, | 231 CP_UTF8, |
232 0, | 232 0, |
233 varName.bstrVal, | 233 varName.bstrVal, |
234 -1, | 234 -1, |
235 (char*) deviceUniqueId
UTF8, | 235 (char*) deviceUniqueId
UTF8, |
236 deviceUniqueIdUTF8Leng
th, | 236 deviceUniqueIdUTF8Leng
th, |
237 NULL, NULL); | 237 NULL, NULL); |
238 if (convResult == 0) | 238 if (convResult == 0) |
239 { | 239 { |
240 WEBRTC_TRACE(webrtc::kTraceError, | 240 WEBRTC_TRACE(webrtc::kTraceError, |
241 webrtc::kTraceVideoCapture, _id
, | 241 webrtc::kTraceVideoCapture, 0, |
242 "Failed to convert device name
to UTF8. %d", | 242 "Failed to convert device name
to UTF8. %d", |
243 GetLastError()); | 243 GetLastError()); |
244 return -1; | 244 return -1; |
245 } | 245 } |
246 if (productUniqueIdUTF8 | 246 if (productUniqueIdUTF8 |
247 && productUniqueIdUTF8Length > 0) | 247 && productUniqueIdUTF8Length > 0) |
248 { | 248 { |
249 GetProductId(deviceUniqueIdUTF8, | 249 GetProductId(deviceUniqueIdUTF8, |
250 productUniqueIdUTF8, | 250 productUniqueIdUTF8, |
251 productUniqueIdUTF8Length); | 251 productUniqueIdUTF8Length); |
252 } | 252 } |
253 } | 253 } |
254 } | 254 } |
255 | 255 |
256 } | 256 } |
257 ++index; // increase the number of valid devices | 257 ++index; // increase the number of valid devices |
258 } | 258 } |
259 } | 259 } |
260 VariantClear(&varName); | 260 VariantClear(&varName); |
261 pBag->Release(); | 261 pBag->Release(); |
262 pM->Release(); | 262 pM->Release(); |
263 } | 263 } |
264 | 264 |
265 } | 265 } |
266 if (deviceNameLength) | 266 if (deviceNameLength) |
267 { | 267 { |
268 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id, "%s %
s", | 268 WEBRTC_TRACE(webrtc::kTraceDebug, |
| 269 webrtc::kTraceVideoCapture, 0, "%s %s", |
269 __FUNCTION__, deviceNameUTF8); | 270 __FUNCTION__, deviceNameUTF8); |
270 } | 271 } |
271 return index; | 272 return index; |
272 } | 273 } |
273 | 274 |
274 IBaseFilter * DeviceInfoDS::GetDeviceFilter( | 275 IBaseFilter * DeviceInfoDS::GetDeviceFilter( |
275 const char* deviceUniqueIdUTF8, | 276 const char* deviceUniqueIdUTF8, |
276 char* productUniqueIdUTF8, | 277 char* productUniqueIdUTF8, |
277 uint32_t productUniqueIdUTF8Length) | 278 uint32_t productUniqueIdUTF8Length) |
278 { | 279 { |
279 | 280 |
280 const int32_t deviceUniqueIdUTF8Length = | 281 const int32_t deviceUniqueIdUTF8Length = |
281 (int32_t) strlen((char*) deviceUniqueIdUTF8); // UTF8 is also NULL termi
nated | 282 (int32_t) strlen((char*) deviceUniqueIdUTF8); // UTF8 is also NULL termi
nated |
282 if (deviceUniqueIdUTF8Length > kVideoCaptureUniqueNameLength) | 283 if (deviceUniqueIdUTF8Length > kVideoCaptureUniqueNameLength) |
283 { | 284 { |
284 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 285 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
285 "Device name too long"); | 286 "Device name too long"); |
286 return NULL; | 287 return NULL; |
287 } | 288 } |
288 | 289 |
289 // enumerate all video capture devices | 290 // enumerate all video capture devices |
290 RELEASE_AND_CLEAR(_dsMonikerDevEnum); | 291 RELEASE_AND_CLEAR(_dsMonikerDevEnum); |
291 HRESULT hr = _dsDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategor
y, | 292 HRESULT hr = _dsDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategor
y, |
292 &_dsMonikerDevEnum, 0); | 293 &_dsMonikerDevEnum, 0); |
293 if (hr != NOERROR) | 294 if (hr != NOERROR) |
294 { | 295 { |
295 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 296 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
296 "Failed to enumerate CLSID_SystemDeviceEnum, error 0x%x." | 297 "Failed to enumerate CLSID_SystemDeviceEnum, error 0x%x." |
297 " No webcam exist?", hr); | 298 " No webcam exist?", hr); |
298 return 0; | 299 return 0; |
299 } | 300 } |
300 _dsMonikerDevEnum->Reset(); | 301 _dsMonikerDevEnum->Reset(); |
301 ULONG cFetched; | 302 ULONG cFetched; |
302 IMoniker *pM; | 303 IMoniker *pM; |
303 | 304 |
304 IBaseFilter *captureFilter = NULL; | 305 IBaseFilter *captureFilter = NULL; |
305 bool deviceFound = false; | 306 bool deviceFound = false; |
(...skipping 28 matching lines...) Expand all Loading... |
334 if (strncmp(tempDevicePathUTF8, | 335 if (strncmp(tempDevicePathUTF8, |
335 (const char*) deviceUniqueIdUTF8, | 336 (const char*) deviceUniqueIdUTF8, |
336 deviceUniqueIdUTF8Length) == 0) | 337 deviceUniqueIdUTF8Length) == 0) |
337 { | 338 { |
338 // We have found the requested device | 339 // We have found the requested device |
339 deviceFound = true; | 340 deviceFound = true; |
340 hr = pM->BindToObject(0, 0, IID_IBaseFilter, | 341 hr = pM->BindToObject(0, 0, IID_IBaseFilter, |
341 (void**) &captureFilter); | 342 (void**) &captureFilter); |
342 if FAILED(hr) | 343 if FAILED(hr) |
343 { | 344 { |
344 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVide
oCapture, | 345 WEBRTC_TRACE( |
345 _id, "Failed to bind to the selected ca
pture device %d",hr); | 346 webrtc::kTraceError, webrtc::kTraceVideoCapture, |
| 347 0, "Failed to bind to the selected capture " |
| 348 "device %d",hr); |
346 } | 349 } |
347 | 350 |
348 if (productUniqueIdUTF8 | 351 if (productUniqueIdUTF8 |
349 && productUniqueIdUTF8Length > 0) // Get the device
name | 352 && productUniqueIdUTF8Length > 0) // Get the device
name |
350 { | 353 { |
351 | 354 |
352 GetProductId(deviceUniqueIdUTF8, | 355 GetProductId(deviceUniqueIdUTF8, |
353 productUniqueIdUTF8, | 356 productUniqueIdUTF8, |
354 productUniqueIdUTF8Length); | 357 productUniqueIdUTF8Length); |
355 } | 358 } |
(...skipping 27 matching lines...) Expand all Loading... |
383 const char* deviceUniqueIdUTF8) | 386 const char* deviceUniqueIdUTF8) |
384 | 387 |
385 { | 388 { |
386 // Reset old capability list | 389 // Reset old capability list |
387 _captureCapabilities.clear(); | 390 _captureCapabilities.clear(); |
388 | 391 |
389 const int32_t deviceUniqueIdUTF8Length = | 392 const int32_t deviceUniqueIdUTF8Length = |
390 (int32_t) strlen((char*) deviceUniqueIdUTF8); | 393 (int32_t) strlen((char*) deviceUniqueIdUTF8); |
391 if (deviceUniqueIdUTF8Length > kVideoCaptureUniqueNameLength) | 394 if (deviceUniqueIdUTF8Length > kVideoCaptureUniqueNameLength) |
392 { | 395 { |
393 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 396 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
394 "Device name too long"); | 397 "Device name too long"); |
395 return -1; | 398 return -1; |
396 } | 399 } |
397 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id, | 400 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, 0, |
398 "CreateCapabilityMap called for device %s", deviceUniqueIdUTF8)
; | 401 "CreateCapabilityMap called for device %s", deviceUniqueIdUTF8)
; |
399 | 402 |
400 | 403 |
401 char productId[kVideoCaptureProductIdLength]; | 404 char productId[kVideoCaptureProductIdLength]; |
402 IBaseFilter* captureDevice = DeviceInfoDS::GetDeviceFilter( | 405 IBaseFilter* captureDevice = DeviceInfoDS::GetDeviceFilter( |
403 deviceUniqueIdUTF8, | 406 deviceUniqueIdUTF8, |
404 productId, | 407 productId, |
405 kVideoCaptureProductIdLength); | 408 kVideoCaptureProductIdLength); |
406 if (!captureDevice) | 409 if (!captureDevice) |
407 return -1; | 410 return -1; |
408 IPin* outputCapturePin = GetOutputPin(captureDevice, GUID_NULL); | 411 IPin* outputCapturePin = GetOutputPin(captureDevice, GUID_NULL); |
409 if (!outputCapturePin) | 412 if (!outputCapturePin) |
410 { | 413 { |
411 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 414 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
412 "Failed to get capture device output pin"); | 415 "Failed to get capture device output pin"); |
413 RELEASE_AND_CLEAR(captureDevice); | 416 RELEASE_AND_CLEAR(captureDevice); |
414 return -1; | 417 return -1; |
415 } | 418 } |
416 IAMExtDevice* extDevice = NULL; | 419 IAMExtDevice* extDevice = NULL; |
417 HRESULT hr = captureDevice->QueryInterface(IID_IAMExtDevice, | 420 HRESULT hr = captureDevice->QueryInterface(IID_IAMExtDevice, |
418 (void **) &extDevice); | 421 (void **) &extDevice); |
419 if (SUCCEEDED(hr) && extDevice) | 422 if (SUCCEEDED(hr) && extDevice) |
420 { | 423 { |
421 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id, | 424 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, 0, |
422 "This is an external device"); | 425 "This is an external device"); |
423 extDevice->Release(); | 426 extDevice->Release(); |
424 } | 427 } |
425 | 428 |
426 IAMStreamConfig* streamConfig = NULL; | 429 IAMStreamConfig* streamConfig = NULL; |
427 hr = outputCapturePin->QueryInterface(IID_IAMStreamConfig, | 430 hr = outputCapturePin->QueryInterface(IID_IAMStreamConfig, |
428 (void**) &streamConfig); | 431 (void**) &streamConfig); |
429 if (FAILED(hr)) | 432 if (FAILED(hr)) |
430 { | 433 { |
431 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 434 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
432 "Failed to get IID_IAMStreamConfig interface from capture d
evice"); | 435 "Failed to get IID_IAMStreamConfig interface from capture d
evice"); |
433 return -1; | 436 return -1; |
434 } | 437 } |
435 | 438 |
436 // this gets the FPS | 439 // this gets the FPS |
437 IAMVideoControl* videoControlConfig = NULL; | 440 IAMVideoControl* videoControlConfig = NULL; |
438 HRESULT hrVC = captureDevice->QueryInterface(IID_IAMVideoControl, | 441 HRESULT hrVC = captureDevice->QueryInterface(IID_IAMVideoControl, |
439 (void**) &videoControlConfig); | 442 (void**) &videoControlConfig); |
440 if (FAILED(hrVC)) | 443 if (FAILED(hrVC)) |
441 { | 444 { |
442 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id, | 445 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, 0, |
443 "IID_IAMVideoControl Interface NOT SUPPORTED"); | 446 "IID_IAMVideoControl Interface NOT SUPPORTED"); |
444 } | 447 } |
445 | 448 |
446 AM_MEDIA_TYPE *pmt = NULL; | 449 AM_MEDIA_TYPE *pmt = NULL; |
447 VIDEO_STREAM_CONFIG_CAPS caps; | 450 VIDEO_STREAM_CONFIG_CAPS caps; |
448 int count, size; | 451 int count, size; |
449 | 452 |
450 hr = streamConfig->GetNumberOfCapabilities(&count, &size); | 453 hr = streamConfig->GetNumberOfCapabilities(&count, &size); |
451 if (FAILED(hr)) | 454 if (FAILED(hr)) |
452 { | 455 { |
453 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 456 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
454 "Failed to GetNumberOfCapabilities"); | 457 "Failed to GetNumberOfCapabilities"); |
455 RELEASE_AND_CLEAR(videoControlConfig); | 458 RELEASE_AND_CLEAR(videoControlConfig); |
456 RELEASE_AND_CLEAR(streamConfig); | 459 RELEASE_AND_CLEAR(streamConfig); |
457 RELEASE_AND_CLEAR(outputCapturePin); | 460 RELEASE_AND_CLEAR(outputCapturePin); |
458 RELEASE_AND_CLEAR(captureDevice); | 461 RELEASE_AND_CLEAR(captureDevice); |
459 return -1; | 462 return -1; |
460 } | 463 } |
461 | 464 |
462 // Check if the device support formattype == FORMAT_VideoInfo2 and FORMAT_Vi
deoInfo. | 465 // Check if the device support formattype == FORMAT_VideoInfo2 and FORMAT_Vi
deoInfo. |
463 // Prefer FORMAT_VideoInfo since some cameras (ZureCam) has been seen having
problem with MJPEG and FORMAT_VideoInfo2 | 466 // Prefer FORMAT_VideoInfo since some cameras (ZureCam) has been seen having
problem with MJPEG and FORMAT_VideoInfo2 |
464 // Interlace flag is only supported in FORMAT_VideoInfo2 | 467 // Interlace flag is only supported in FORMAT_VideoInfo2 |
465 bool supportFORMAT_VideoInfo2 = false; | 468 bool supportFORMAT_VideoInfo2 = false; |
466 bool supportFORMAT_VideoInfo = false; | 469 bool supportFORMAT_VideoInfo = false; |
467 bool foundInterlacedFormat = false; | 470 bool foundInterlacedFormat = false; |
468 GUID preferedVideoFormat = FORMAT_VideoInfo; | 471 GUID preferedVideoFormat = FORMAT_VideoInfo; |
469 for (int32_t tmp = 0; tmp < count; ++tmp) | 472 for (int32_t tmp = 0; tmp < count; ++tmp) |
470 { | 473 { |
471 hr = streamConfig->GetStreamCaps(tmp, &pmt, | 474 hr = streamConfig->GetStreamCaps(tmp, &pmt, |
472 reinterpret_cast<BYTE*> (&caps)); | 475 reinterpret_cast<BYTE*> (&caps)); |
473 if (!FAILED(hr)) | 476 if (!FAILED(hr)) |
474 { | 477 { |
475 if (pmt->majortype == MEDIATYPE_Video | 478 if (pmt->majortype == MEDIATYPE_Video |
476 && pmt->formattype == FORMAT_VideoInfo2) | 479 && pmt->formattype == FORMAT_VideoInfo2) |
477 { | 480 { |
478 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _i
d, | 481 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, 0, |
479 " Device support FORMAT_VideoInfo2"); | 482 " Device support FORMAT_VideoInfo2"); |
480 supportFORMAT_VideoInfo2 = true; | 483 supportFORMAT_VideoInfo2 = true; |
481 VIDEOINFOHEADER2* h = | 484 VIDEOINFOHEADER2* h = |
482 reinterpret_cast<VIDEOINFOHEADER2*> (pmt->pbFormat); | 485 reinterpret_cast<VIDEOINFOHEADER2*> (pmt->pbFormat); |
483 assert(h); | 486 assert(h); |
484 foundInterlacedFormat |= h->dwInterlaceFlags | 487 foundInterlacedFormat |= h->dwInterlaceFlags |
485 & (AMINTERLACE_IsInterlaced | 488 & (AMINTERLACE_IsInterlaced |
486 | AMINTERLACE_DisplayModeBobOnly); | 489 | AMINTERLACE_DisplayModeBobOnly); |
487 } | 490 } |
488 if (pmt->majortype == MEDIATYPE_Video | 491 if (pmt->majortype == MEDIATYPE_Video |
489 && pmt->formattype == FORMAT_VideoInfo) | 492 && pmt->formattype == FORMAT_VideoInfo) |
490 { | 493 { |
491 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _i
d, | 494 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, 0, |
492 " Device support FORMAT_VideoInfo2"); | 495 " Device support FORMAT_VideoInfo2"); |
493 supportFORMAT_VideoInfo = true; | 496 supportFORMAT_VideoInfo = true; |
494 } | 497 } |
495 } | 498 } |
496 } | 499 } |
497 if (supportFORMAT_VideoInfo2) | 500 if (supportFORMAT_VideoInfo2) |
498 { | 501 { |
499 if (supportFORMAT_VideoInfo && !foundInterlacedFormat) | 502 if (supportFORMAT_VideoInfo && !foundInterlacedFormat) |
500 { | 503 { |
501 preferedVideoFormat = FORMAT_VideoInfo; | 504 preferedVideoFormat = FORMAT_VideoInfo; |
502 } | 505 } |
503 else | 506 else |
504 { | 507 { |
505 preferedVideoFormat = FORMAT_VideoInfo2; | 508 preferedVideoFormat = FORMAT_VideoInfo2; |
506 } | 509 } |
507 } | 510 } |
508 | 511 |
509 for (int32_t tmp = 0; tmp < count; ++tmp) | 512 for (int32_t tmp = 0; tmp < count; ++tmp) |
510 { | 513 { |
511 hr = streamConfig->GetStreamCaps(tmp, &pmt, | 514 hr = streamConfig->GetStreamCaps(tmp, &pmt, |
512 reinterpret_cast<BYTE*> (&caps)); | 515 reinterpret_cast<BYTE*> (&caps)); |
513 if (FAILED(hr)) | 516 if (FAILED(hr)) |
514 { | 517 { |
515 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 518 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
516 "Failed to GetStreamCaps"); | 519 "Failed to GetStreamCaps"); |
517 RELEASE_AND_CLEAR(videoControlConfig); | 520 RELEASE_AND_CLEAR(videoControlConfig); |
518 RELEASE_AND_CLEAR(streamConfig); | 521 RELEASE_AND_CLEAR(streamConfig); |
519 RELEASE_AND_CLEAR(outputCapturePin); | 522 RELEASE_AND_CLEAR(outputCapturePin); |
520 RELEASE_AND_CLEAR(captureDevice); | 523 RELEASE_AND_CLEAR(captureDevice); |
521 return -1; | 524 return -1; |
522 } | 525 } |
523 | 526 |
524 if (pmt->majortype == MEDIATYPE_Video | 527 if (pmt->majortype == MEDIATYPE_Video |
525 && pmt->formattype == preferedVideoFormat) | 528 && pmt->formattype == preferedVideoFormat) |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 0 != (maxFPS = GetMaxOfFrameArray(frameDurationList, | 580 0 != (maxFPS = GetMaxOfFrameArray(frameDurationList, |
578 listSize))) | 581 listSize))) |
579 { | 582 { |
580 capability.maxFPS = static_cast<int> (10000000 | 583 capability.maxFPS = static_cast<int> (10000000 |
581 / maxFPS); | 584 / maxFPS); |
582 capability.supportFrameRateControl = true; | 585 capability.supportFrameRateControl = true; |
583 } | 586 } |
584 else // use existing method | 587 else // use existing method |
585 { | 588 { |
586 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture
, | 589 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture
, |
587 _id, | 590 0, |
588 "GetMaxAvailableFrameRate NOT SUPPORTED"); | 591 "GetMaxAvailableFrameRate NOT SUPPORTED"); |
589 if (avgTimePerFrame > 0) | 592 if (avgTimePerFrame > 0) |
590 capability.maxFPS = static_cast<int> (10000000 | 593 capability.maxFPS = static_cast<int> (10000000 |
591 / avgTimePerFrame
); | 594 / avgTimePerFrame
); |
592 else | 595 else |
593 capability.maxFPS = 0; | 596 capability.maxFPS = 0; |
594 } | 597 } |
595 } | 598 } |
596 else // use existing method in case IAMVideoControl is not supported | 599 else // use existing method in case IAMVideoControl is not supported |
597 { | 600 { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 || pmt->subtype == MEDIASUBTYPE_dvhd) // If this is an exter
nal DV camera | 635 || pmt->subtype == MEDIASUBTYPE_dvhd) // If this is an exter
nal DV camera |
633 { | 636 { |
634 capability.rawType = kVideoYUY2;// MS DV filter seems to create
this type | 637 capability.rawType = kVideoYUY2;// MS DV filter seems to create
this type |
635 } | 638 } |
636 else if (pmt->subtype == MEDIASUBTYPE_UYVY) // Seen used by Declink
capture cards | 639 else if (pmt->subtype == MEDIASUBTYPE_UYVY) // Seen used by Declink
capture cards |
637 { | 640 { |
638 capability.rawType = kVideoUYVY; | 641 capability.rawType = kVideoUYVY; |
639 } | 642 } |
640 else if (pmt->subtype == MEDIASUBTYPE_HDYC) // Seen used by Declink
capture cards. Uses BT. 709 color. Not entiry correct to use UYVY. http://en.wik
ipedia.org/wiki/YCbCr | 643 else if (pmt->subtype == MEDIASUBTYPE_HDYC) // Seen used by Declink
capture cards. Uses BT. 709 color. Not entiry correct to use UYVY. http://en.wik
ipedia.org/wiki/YCbCr |
641 { | 644 { |
642 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture,
_id, | 645 WEBRTC_TRACE(webrtc::kTraceWarning, |
| 646 webrtc::kTraceVideoCapture, 0, |
643 "Device support HDYC."); | 647 "Device support HDYC."); |
644 capability.rawType = kVideoUYVY; | 648 capability.rawType = kVideoUYVY; |
645 } | 649 } |
646 else | 650 else |
647 { | 651 { |
648 WCHAR strGuid[39]; | 652 WCHAR strGuid[39]; |
649 StringFromGUID2(pmt->subtype, strGuid, 39); | 653 StringFromGUID2(pmt->subtype, strGuid, 39); |
650 WEBRTC_TRACE( webrtc::kTraceWarning, | 654 WEBRTC_TRACE( webrtc::kTraceWarning, |
651 webrtc::kTraceVideoCapture, _id, | 655 webrtc::kTraceVideoCapture, 0, |
652 "Device support unknown media type %ls, width %d, h
eight %d", | 656 "Device support unknown media type %ls, width %d, h
eight %d", |
653 strGuid); | 657 strGuid); |
654 continue; | 658 continue; |
655 } | 659 } |
656 | 660 |
657 // Get the expected capture delay from the static list | 661 // Get the expected capture delay from the static list |
658 capability.expectedCaptureDelay | 662 capability.expectedCaptureDelay |
659 = GetExpectedCaptureDelay(WindowsCaptureDelays, | 663 = GetExpectedCaptureDelay(WindowsCaptureDelays, |
660 NoWindowsCaptureDelays, | 664 NoWindowsCaptureDelays, |
661 productId, | 665 productId, |
662 capability.width, | 666 capability.width, |
663 capability.height); | 667 capability.height); |
664 _captureCapabilities.push_back(capability); | 668 _captureCapabilities.push_back(capability); |
665 _captureCapabilitiesWindows.push_back(capability); | 669 _captureCapabilitiesWindows.push_back(capability); |
666 WEBRTC_TRACE( webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id, | 670 WEBRTC_TRACE( webrtc::kTraceInfo, webrtc::kTraceVideoCapture, 0, |
667 "Camera capability, width:%d height:%d type:%d fps:%d", | 671 "Camera capability, width:%d height:%d type:%d fps:%d", |
668 capability.width, capability.height, | 672 capability.width, capability.height, |
669 capability.rawType, capability.maxFPS); | 673 capability.rawType, capability.maxFPS); |
670 } | 674 } |
671 DeleteMediaType(pmt); | 675 DeleteMediaType(pmt); |
672 pmt = NULL; | 676 pmt = NULL; |
673 } | 677 } |
674 RELEASE_AND_CLEAR(streamConfig); | 678 RELEASE_AND_CLEAR(streamConfig); |
675 RELEASE_AND_CLEAR(videoControlConfig); | 679 RELEASE_AND_CLEAR(videoControlConfig); |
676 RELEASE_AND_CLEAR(outputCapturePin); | 680 RELEASE_AND_CLEAR(outputCapturePin); |
677 RELEASE_AND_CLEAR(captureDevice); // Release the capture device | 681 RELEASE_AND_CLEAR(captureDevice); // Release the capture device |
678 | 682 |
679 // Store the new used device name | 683 // Store the new used device name |
680 _lastUsedDeviceNameLength = deviceUniqueIdUTF8Length; | 684 _lastUsedDeviceNameLength = deviceUniqueIdUTF8Length; |
681 _lastUsedDeviceName = (char*) realloc(_lastUsedDeviceName, | 685 _lastUsedDeviceName = (char*) realloc(_lastUsedDeviceName, |
682 _lastUsedDeviceNameLength | 686 _lastUsedDeviceNameLength |
683 + 1); | 687 + 1); |
684 memcpy(_lastUsedDeviceName, deviceUniqueIdUTF8, _lastUsedDeviceNameLength+ 1
); | 688 memcpy(_lastUsedDeviceName, deviceUniqueIdUTF8, _lastUsedDeviceNameLength+ 1
); |
685 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id, | 689 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, 0, |
686 "CreateCapabilityMap %d", _captureCapabilities.size()); | 690 "CreateCapabilityMap %d", _captureCapabilities.size()); |
687 | 691 |
688 return static_cast<int32_t>(_captureCapabilities.size()); | 692 return static_cast<int32_t>(_captureCapabilities.size()); |
689 } | 693 } |
690 | 694 |
691 /* Constructs a product ID from the Windows DevicePath. on a USB device the devi
cePath contains product id and vendor id. | 695 /* Constructs a product ID from the Windows DevicePath. on a USB device the devi
cePath contains product id and vendor id. |
692 This seems to work for firewire as well | 696 This seems to work for firewire as well |
693 /* Example of device path | 697 /* Example of device path |
694 "\\?\usb#vid_0408&pid_2010&mi_00#7&258e7aaf&0&0000#{65e8773d-8f56-11d0-a3b9-00a
0c9223196}\global" | 698 "\\?\usb#vid_0408&pid_2010&mi_00#7&258e7aaf&0&0000#{65e8773d-8f56-11d0-a3b9-00a
0c9223196}\global" |
695 "\\?\avc#sony&dv-vcr&camcorder&dv#65b2d50301460008#{65e8773d-8f56-11d0-a3b9-00a
0c9223196}\global" | 699 "\\?\avc#sony&dv-vcr&camcorder&dv#65b2d50301460008#{65e8773d-8f56-11d0-a3b9-00a
0c9223196}\global" |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 // Release memory. | 792 // Release memory. |
789 if (uuid.pElems) | 793 if (uuid.pElems) |
790 { | 794 { |
791 CoTaskMemFree(uuid.pElems); | 795 CoTaskMemFree(uuid.pElems); |
792 } | 796 } |
793 filter->Release(); | 797 filter->Release(); |
794 return 0; | 798 return 0; |
795 } | 799 } |
796 } // namespace videocapturemodule | 800 } // namespace videocapturemodule |
797 } // namespace webrtc | 801 } // namespace webrtc |
OLD | NEW |