| 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, webrtc::kTraceVideoCapture, 0, "%s %s"
, |
| 269 __FUNCTION__, deviceNameUTF8); | 269 __FUNCTION__, deviceNameUTF8); |
| 270 } | 270 } |
| 271 return index; | 271 return index; |
| 272 } | 272 } |
| 273 | 273 |
| 274 IBaseFilter * DeviceInfoDS::GetDeviceFilter( | 274 IBaseFilter * DeviceInfoDS::GetDeviceFilter( |
| 275 const char* deviceUniqueIdUTF8, | 275 const char* deviceUniqueIdUTF8, |
| 276 char* productUniqueIdUTF8, | 276 char* productUniqueIdUTF8, |
| 277 uint32_t productUniqueIdUTF8Length) | 277 uint32_t productUniqueIdUTF8Length) |
| 278 { | 278 { |
| 279 | 279 |
| 280 const int32_t deviceUniqueIdUTF8Length = | 280 const int32_t deviceUniqueIdUTF8Length = |
| 281 (int32_t) strlen((char*) deviceUniqueIdUTF8); // UTF8 is also NULL termi
nated | 281 (int32_t) strlen((char*) deviceUniqueIdUTF8); // UTF8 is also NULL termi
nated |
| 282 if (deviceUniqueIdUTF8Length > kVideoCaptureUniqueNameLength) | 282 if (deviceUniqueIdUTF8Length > kVideoCaptureUniqueNameLength) |
| 283 { | 283 { |
| 284 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 284 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
| 285 "Device name too long"); | 285 "Device name too long"); |
| 286 return NULL; | 286 return NULL; |
| 287 } | 287 } |
| 288 | 288 |
| 289 // enumerate all video capture devices | 289 // enumerate all video capture devices |
| 290 RELEASE_AND_CLEAR(_dsMonikerDevEnum); | 290 RELEASE_AND_CLEAR(_dsMonikerDevEnum); |
| 291 HRESULT hr = _dsDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategor
y, | 291 HRESULT hr = _dsDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategor
y, |
| 292 &_dsMonikerDevEnum, 0); | 292 &_dsMonikerDevEnum, 0); |
| 293 if (hr != NOERROR) | 293 if (hr != NOERROR) |
| 294 { | 294 { |
| 295 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 295 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
| 296 "Failed to enumerate CLSID_SystemDeviceEnum, error 0x%x." | 296 "Failed to enumerate CLSID_SystemDeviceEnum, error 0x%x." |
| 297 " No webcam exist?", hr); | 297 " No webcam exist?", hr); |
| 298 return 0; | 298 return 0; |
| 299 } | 299 } |
| 300 _dsMonikerDevEnum->Reset(); | 300 _dsMonikerDevEnum->Reset(); |
| 301 ULONG cFetched; | 301 ULONG cFetched; |
| 302 IMoniker *pM; | 302 IMoniker *pM; |
| 303 | 303 |
| 304 IBaseFilter *captureFilter = NULL; | 304 IBaseFilter *captureFilter = NULL; |
| 305 bool deviceFound = false; | 305 bool deviceFound = false; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 335 (const char*) deviceUniqueIdUTF8, | 335 (const char*) deviceUniqueIdUTF8, |
| 336 deviceUniqueIdUTF8Length) == 0) | 336 deviceUniqueIdUTF8Length) == 0) |
| 337 { | 337 { |
| 338 // We have found the requested device | 338 // We have found the requested device |
| 339 deviceFound = true; | 339 deviceFound = true; |
| 340 hr = pM->BindToObject(0, 0, IID_IBaseFilter, | 340 hr = pM->BindToObject(0, 0, IID_IBaseFilter, |
| 341 (void**) &captureFilter); | 341 (void**) &captureFilter); |
| 342 if FAILED(hr) | 342 if FAILED(hr) |
| 343 { | 343 { |
| 344 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVide
oCapture, | 344 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVide
oCapture, |
| 345 _id, "Failed to bind to the selected ca
pture device %d",hr); | 345 0, "Failed to bind to the selected capt
ure device %d",hr); |
| 346 } | 346 } |
| 347 | 347 |
| 348 if (productUniqueIdUTF8 | 348 if (productUniqueIdUTF8 |
| 349 && productUniqueIdUTF8Length > 0) // Get the device
name | 349 && productUniqueIdUTF8Length > 0) // Get the device
name |
| 350 { | 350 { |
| 351 | 351 |
| 352 GetProductId(deviceUniqueIdUTF8, | 352 GetProductId(deviceUniqueIdUTF8, |
| 353 productUniqueIdUTF8, | 353 productUniqueIdUTF8, |
| 354 productUniqueIdUTF8Length); | 354 productUniqueIdUTF8Length); |
| 355 } | 355 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 383 const char* deviceUniqueIdUTF8) | 383 const char* deviceUniqueIdUTF8) |
| 384 | 384 |
| 385 { | 385 { |
| 386 // Reset old capability list | 386 // Reset old capability list |
| 387 _captureCapabilities.clear(); | 387 _captureCapabilities.clear(); |
| 388 | 388 |
| 389 const int32_t deviceUniqueIdUTF8Length = | 389 const int32_t deviceUniqueIdUTF8Length = |
| 390 (int32_t) strlen((char*) deviceUniqueIdUTF8); | 390 (int32_t) strlen((char*) deviceUniqueIdUTF8); |
| 391 if (deviceUniqueIdUTF8Length > kVideoCaptureUniqueNameLength) | 391 if (deviceUniqueIdUTF8Length > kVideoCaptureUniqueNameLength) |
| 392 { | 392 { |
| 393 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 393 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
| 394 "Device name too long"); | 394 "Device name too long"); |
| 395 return -1; | 395 return -1; |
| 396 } | 396 } |
| 397 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id, | 397 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, 0, |
| 398 "CreateCapabilityMap called for device %s", deviceUniqueIdUTF8)
; | 398 "CreateCapabilityMap called for device %s", deviceUniqueIdUTF8)
; |
| 399 | 399 |
| 400 | 400 |
| 401 char productId[kVideoCaptureProductIdLength]; | 401 char productId[kVideoCaptureProductIdLength]; |
| 402 IBaseFilter* captureDevice = DeviceInfoDS::GetDeviceFilter( | 402 IBaseFilter* captureDevice = DeviceInfoDS::GetDeviceFilter( |
| 403 deviceUniqueIdUTF8, | 403 deviceUniqueIdUTF8, |
| 404 productId, | 404 productId, |
| 405 kVideoCaptureProductIdLength); | 405 kVideoCaptureProductIdLength); |
| 406 if (!captureDevice) | 406 if (!captureDevice) |
| 407 return -1; | 407 return -1; |
| 408 IPin* outputCapturePin = GetOutputPin(captureDevice, GUID_NULL); | 408 IPin* outputCapturePin = GetOutputPin(captureDevice, GUID_NULL); |
| 409 if (!outputCapturePin) | 409 if (!outputCapturePin) |
| 410 { | 410 { |
| 411 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 411 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
| 412 "Failed to get capture device output pin"); | 412 "Failed to get capture device output pin"); |
| 413 RELEASE_AND_CLEAR(captureDevice); | 413 RELEASE_AND_CLEAR(captureDevice); |
| 414 return -1; | 414 return -1; |
| 415 } | 415 } |
| 416 IAMExtDevice* extDevice = NULL; | 416 IAMExtDevice* extDevice = NULL; |
| 417 HRESULT hr = captureDevice->QueryInterface(IID_IAMExtDevice, | 417 HRESULT hr = captureDevice->QueryInterface(IID_IAMExtDevice, |
| 418 (void **) &extDevice); | 418 (void **) &extDevice); |
| 419 if (SUCCEEDED(hr) && extDevice) | 419 if (SUCCEEDED(hr) && extDevice) |
| 420 { | 420 { |
| 421 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id, | 421 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, 0, |
| 422 "This is an external device"); | 422 "This is an external device"); |
| 423 extDevice->Release(); | 423 extDevice->Release(); |
| 424 } | 424 } |
| 425 | 425 |
| 426 IAMStreamConfig* streamConfig = NULL; | 426 IAMStreamConfig* streamConfig = NULL; |
| 427 hr = outputCapturePin->QueryInterface(IID_IAMStreamConfig, | 427 hr = outputCapturePin->QueryInterface(IID_IAMStreamConfig, |
| 428 (void**) &streamConfig); | 428 (void**) &streamConfig); |
| 429 if (FAILED(hr)) | 429 if (FAILED(hr)) |
| 430 { | 430 { |
| 431 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 431 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
| 432 "Failed to get IID_IAMStreamConfig interface from capture d
evice"); | 432 "Failed to get IID_IAMStreamConfig interface from capture d
evice"); |
| 433 return -1; | 433 return -1; |
| 434 } | 434 } |
| 435 | 435 |
| 436 // this gets the FPS | 436 // this gets the FPS |
| 437 IAMVideoControl* videoControlConfig = NULL; | 437 IAMVideoControl* videoControlConfig = NULL; |
| 438 HRESULT hrVC = captureDevice->QueryInterface(IID_IAMVideoControl, | 438 HRESULT hrVC = captureDevice->QueryInterface(IID_IAMVideoControl, |
| 439 (void**) &videoControlConfig); | 439 (void**) &videoControlConfig); |
| 440 if (FAILED(hrVC)) | 440 if (FAILED(hrVC)) |
| 441 { | 441 { |
| 442 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id, | 442 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, 0, |
| 443 "IID_IAMVideoControl Interface NOT SUPPORTED"); | 443 "IID_IAMVideoControl Interface NOT SUPPORTED"); |
| 444 } | 444 } |
| 445 | 445 |
| 446 AM_MEDIA_TYPE *pmt = NULL; | 446 AM_MEDIA_TYPE *pmt = NULL; |
| 447 VIDEO_STREAM_CONFIG_CAPS caps; | 447 VIDEO_STREAM_CONFIG_CAPS caps; |
| 448 int count, size; | 448 int count, size; |
| 449 | 449 |
| 450 hr = streamConfig->GetNumberOfCapabilities(&count, &size); | 450 hr = streamConfig->GetNumberOfCapabilities(&count, &size); |
| 451 if (FAILED(hr)) | 451 if (FAILED(hr)) |
| 452 { | 452 { |
| 453 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 453 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
| 454 "Failed to GetNumberOfCapabilities"); | 454 "Failed to GetNumberOfCapabilities"); |
| 455 RELEASE_AND_CLEAR(videoControlConfig); | 455 RELEASE_AND_CLEAR(videoControlConfig); |
| 456 RELEASE_AND_CLEAR(streamConfig); | 456 RELEASE_AND_CLEAR(streamConfig); |
| 457 RELEASE_AND_CLEAR(outputCapturePin); | 457 RELEASE_AND_CLEAR(outputCapturePin); |
| 458 RELEASE_AND_CLEAR(captureDevice); | 458 RELEASE_AND_CLEAR(captureDevice); |
| 459 return -1; | 459 return -1; |
| 460 } | 460 } |
| 461 | 461 |
| 462 // Check if the device support formattype == FORMAT_VideoInfo2 and FORMAT_Vi
deoInfo. | 462 // 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 | 463 // 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 | 464 // Interlace flag is only supported in FORMAT_VideoInfo2 |
| 465 bool supportFORMAT_VideoInfo2 = false; | 465 bool supportFORMAT_VideoInfo2 = false; |
| 466 bool supportFORMAT_VideoInfo = false; | 466 bool supportFORMAT_VideoInfo = false; |
| 467 bool foundInterlacedFormat = false; | 467 bool foundInterlacedFormat = false; |
| 468 GUID preferedVideoFormat = FORMAT_VideoInfo; | 468 GUID preferedVideoFormat = FORMAT_VideoInfo; |
| 469 for (int32_t tmp = 0; tmp < count; ++tmp) | 469 for (int32_t tmp = 0; tmp < count; ++tmp) |
| 470 { | 470 { |
| 471 hr = streamConfig->GetStreamCaps(tmp, &pmt, | 471 hr = streamConfig->GetStreamCaps(tmp, &pmt, |
| 472 reinterpret_cast<BYTE*> (&caps)); | 472 reinterpret_cast<BYTE*> (&caps)); |
| 473 if (!FAILED(hr)) | 473 if (!FAILED(hr)) |
| 474 { | 474 { |
| 475 if (pmt->majortype == MEDIATYPE_Video | 475 if (pmt->majortype == MEDIATYPE_Video |
| 476 && pmt->formattype == FORMAT_VideoInfo2) | 476 && pmt->formattype == FORMAT_VideoInfo2) |
| 477 { | 477 { |
| 478 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _i
d, | 478 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, 0, |
| 479 " Device support FORMAT_VideoInfo2"); | 479 " Device support FORMAT_VideoInfo2"); |
| 480 supportFORMAT_VideoInfo2 = true; | 480 supportFORMAT_VideoInfo2 = true; |
| 481 VIDEOINFOHEADER2* h = | 481 VIDEOINFOHEADER2* h = |
| 482 reinterpret_cast<VIDEOINFOHEADER2*> (pmt->pbFormat); | 482 reinterpret_cast<VIDEOINFOHEADER2*> (pmt->pbFormat); |
| 483 assert(h); | 483 assert(h); |
| 484 foundInterlacedFormat |= h->dwInterlaceFlags | 484 foundInterlacedFormat |= h->dwInterlaceFlags |
| 485 & (AMINTERLACE_IsInterlaced | 485 & (AMINTERLACE_IsInterlaced |
| 486 | AMINTERLACE_DisplayModeBobOnly); | 486 | AMINTERLACE_DisplayModeBobOnly); |
| 487 } | 487 } |
| 488 if (pmt->majortype == MEDIATYPE_Video | 488 if (pmt->majortype == MEDIATYPE_Video |
| 489 && pmt->formattype == FORMAT_VideoInfo) | 489 && pmt->formattype == FORMAT_VideoInfo) |
| 490 { | 490 { |
| 491 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _i
d, | 491 WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, 0, |
| 492 " Device support FORMAT_VideoInfo2"); | 492 " Device support FORMAT_VideoInfo2"); |
| 493 supportFORMAT_VideoInfo = true; | 493 supportFORMAT_VideoInfo = true; |
| 494 } | 494 } |
| 495 } | 495 } |
| 496 } | 496 } |
| 497 if (supportFORMAT_VideoInfo2) | 497 if (supportFORMAT_VideoInfo2) |
| 498 { | 498 { |
| 499 if (supportFORMAT_VideoInfo && !foundInterlacedFormat) | 499 if (supportFORMAT_VideoInfo && !foundInterlacedFormat) |
| 500 { | 500 { |
| 501 preferedVideoFormat = FORMAT_VideoInfo; | 501 preferedVideoFormat = FORMAT_VideoInfo; |
| 502 } | 502 } |
| 503 else | 503 else |
| 504 { | 504 { |
| 505 preferedVideoFormat = FORMAT_VideoInfo2; | 505 preferedVideoFormat = FORMAT_VideoInfo2; |
| 506 } | 506 } |
| 507 } | 507 } |
| 508 | 508 |
| 509 for (int32_t tmp = 0; tmp < count; ++tmp) | 509 for (int32_t tmp = 0; tmp < count; ++tmp) |
| 510 { | 510 { |
| 511 hr = streamConfig->GetStreamCaps(tmp, &pmt, | 511 hr = streamConfig->GetStreamCaps(tmp, &pmt, |
| 512 reinterpret_cast<BYTE*> (&caps)); | 512 reinterpret_cast<BYTE*> (&caps)); |
| 513 if (FAILED(hr)) | 513 if (FAILED(hr)) |
| 514 { | 514 { |
| 515 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, | 515 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0, |
| 516 "Failed to GetStreamCaps"); | 516 "Failed to GetStreamCaps"); |
| 517 RELEASE_AND_CLEAR(videoControlConfig); | 517 RELEASE_AND_CLEAR(videoControlConfig); |
| 518 RELEASE_AND_CLEAR(streamConfig); | 518 RELEASE_AND_CLEAR(streamConfig); |
| 519 RELEASE_AND_CLEAR(outputCapturePin); | 519 RELEASE_AND_CLEAR(outputCapturePin); |
| 520 RELEASE_AND_CLEAR(captureDevice); | 520 RELEASE_AND_CLEAR(captureDevice); |
| 521 return -1; | 521 return -1; |
| 522 } | 522 } |
| 523 | 523 |
| 524 if (pmt->majortype == MEDIATYPE_Video | 524 if (pmt->majortype == MEDIATYPE_Video |
| 525 && pmt->formattype == preferedVideoFormat) | 525 && pmt->formattype == preferedVideoFormat) |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 577 0 != (maxFPS = GetMaxOfFrameArray(frameDurationList, | 577 0 != (maxFPS = GetMaxOfFrameArray(frameDurationList, |
| 578 listSize))) | 578 listSize))) |
| 579 { | 579 { |
| 580 capability.maxFPS = static_cast<int> (10000000 | 580 capability.maxFPS = static_cast<int> (10000000 |
| 581 / maxFPS); | 581 / maxFPS); |
| 582 capability.supportFrameRateControl = true; | 582 capability.supportFrameRateControl = true; |
| 583 } | 583 } |
| 584 else // use existing method | 584 else // use existing method |
| 585 { | 585 { |
| 586 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture
, | 586 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture
, |
| 587 _id, | 587 0, |
| 588 "GetMaxAvailableFrameRate NOT SUPPORTED"); | 588 "GetMaxAvailableFrameRate NOT SUPPORTED"); |
| 589 if (avgTimePerFrame > 0) | 589 if (avgTimePerFrame > 0) |
| 590 capability.maxFPS = static_cast<int> (10000000 | 590 capability.maxFPS = static_cast<int> (10000000 |
| 591 / avgTimePerFrame
); | 591 / avgTimePerFrame
); |
| 592 else | 592 else |
| 593 capability.maxFPS = 0; | 593 capability.maxFPS = 0; |
| 594 } | 594 } |
| 595 } | 595 } |
| 596 else // use existing method in case IAMVideoControl is not supported | 596 else // use existing method in case IAMVideoControl is not supported |
| 597 { | 597 { |
| (...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 | 632 || pmt->subtype == MEDIASUBTYPE_dvhd) // If this is an exter
nal DV camera |
| 633 { | 633 { |
| 634 capability.rawType = kVideoYUY2;// MS DV filter seems to create
this type | 634 capability.rawType = kVideoYUY2;// MS DV filter seems to create
this type |
| 635 } | 635 } |
| 636 else if (pmt->subtype == MEDIASUBTYPE_UYVY) // Seen used by Declink
capture cards | 636 else if (pmt->subtype == MEDIASUBTYPE_UYVY) // Seen used by Declink
capture cards |
| 637 { | 637 { |
| 638 capability.rawType = kVideoUYVY; | 638 capability.rawType = kVideoUYVY; |
| 639 } | 639 } |
| 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 | 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 |
| 641 { | 641 { |
| 642 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture,
_id, | 642 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture,
0, |
| 643 "Device support HDYC."); | 643 "Device support HDYC."); |
| 644 capability.rawType = kVideoUYVY; | 644 capability.rawType = kVideoUYVY; |
| 645 } | 645 } |
| 646 else | 646 else |
| 647 { | 647 { |
| 648 WCHAR strGuid[39]; | 648 WCHAR strGuid[39]; |
| 649 StringFromGUID2(pmt->subtype, strGuid, 39); | 649 StringFromGUID2(pmt->subtype, strGuid, 39); |
| 650 WEBRTC_TRACE( webrtc::kTraceWarning, | 650 WEBRTC_TRACE( webrtc::kTraceWarning, |
| 651 webrtc::kTraceVideoCapture, _id, | 651 webrtc::kTraceVideoCapture, 0, |
| 652 "Device support unknown media type %ls, width %d, h
eight %d", | 652 "Device support unknown media type %ls, width %d, h
eight %d", |
| 653 strGuid); | 653 strGuid); |
| 654 continue; | 654 continue; |
| 655 } | 655 } |
| 656 | 656 |
| 657 // Get the expected capture delay from the static list | 657 // Get the expected capture delay from the static list |
| 658 capability.expectedCaptureDelay | 658 capability.expectedCaptureDelay |
| 659 = GetExpectedCaptureDelay(WindowsCaptureDelays, | 659 = GetExpectedCaptureDelay(WindowsCaptureDelays, |
| 660 NoWindowsCaptureDelays, | 660 NoWindowsCaptureDelays, |
| 661 productId, | 661 productId, |
| 662 capability.width, | 662 capability.width, |
| 663 capability.height); | 663 capability.height); |
| 664 _captureCapabilities.push_back(capability); | 664 _captureCapabilities.push_back(capability); |
| 665 _captureCapabilitiesWindows.push_back(capability); | 665 _captureCapabilitiesWindows.push_back(capability); |
| 666 WEBRTC_TRACE( webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id, | 666 WEBRTC_TRACE( webrtc::kTraceInfo, webrtc::kTraceVideoCapture, 0, |
| 667 "Camera capability, width:%d height:%d type:%d fps:%d", | 667 "Camera capability, width:%d height:%d type:%d fps:%d", |
| 668 capability.width, capability.height, | 668 capability.width, capability.height, |
| 669 capability.rawType, capability.maxFPS); | 669 capability.rawType, capability.maxFPS); |
| 670 } | 670 } |
| 671 DeleteMediaType(pmt); | 671 DeleteMediaType(pmt); |
| 672 pmt = NULL; | 672 pmt = NULL; |
| 673 } | 673 } |
| 674 RELEASE_AND_CLEAR(streamConfig); | 674 RELEASE_AND_CLEAR(streamConfig); |
| 675 RELEASE_AND_CLEAR(videoControlConfig); | 675 RELEASE_AND_CLEAR(videoControlConfig); |
| 676 RELEASE_AND_CLEAR(outputCapturePin); | 676 RELEASE_AND_CLEAR(outputCapturePin); |
| 677 RELEASE_AND_CLEAR(captureDevice); // Release the capture device | 677 RELEASE_AND_CLEAR(captureDevice); // Release the capture device |
| 678 | 678 |
| 679 // Store the new used device name | 679 // Store the new used device name |
| 680 _lastUsedDeviceNameLength = deviceUniqueIdUTF8Length; | 680 _lastUsedDeviceNameLength = deviceUniqueIdUTF8Length; |
| 681 _lastUsedDeviceName = (char*) realloc(_lastUsedDeviceName, | 681 _lastUsedDeviceName = (char*) realloc(_lastUsedDeviceName, |
| 682 _lastUsedDeviceNameLength | 682 _lastUsedDeviceNameLength |
| 683 + 1); | 683 + 1); |
| 684 memcpy(_lastUsedDeviceName, deviceUniqueIdUTF8, _lastUsedDeviceNameLength+ 1
); | 684 memcpy(_lastUsedDeviceName, deviceUniqueIdUTF8, _lastUsedDeviceNameLength+ 1
); |
| 685 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id, | 685 WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, 0, |
| 686 "CreateCapabilityMap %d", _captureCapabilities.size()); | 686 "CreateCapabilityMap %d", _captureCapabilities.size()); |
| 687 | 687 |
| 688 return static_cast<int32_t>(_captureCapabilities.size()); | 688 return static_cast<int32_t>(_captureCapabilities.size()); |
| 689 } | 689 } |
| 690 | 690 |
| 691 /* Constructs a product ID from the Windows DevicePath. on a USB device the devi
cePath contains product id and vendor id. | 691 /* 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 | 692 This seems to work for firewire as well |
| 693 /* Example of device path | 693 /* Example of device path |
| 694 "\\?\usb#vid_0408&pid_2010&mi_00#7&258e7aaf&0&0000#{65e8773d-8f56-11d0-a3b9-00a
0c9223196}\global" | 694 "\\?\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" | 695 "\\?\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. | 788 // Release memory. |
| 789 if (uuid.pElems) | 789 if (uuid.pElems) |
| 790 { | 790 { |
| 791 CoTaskMemFree(uuid.pElems); | 791 CoTaskMemFree(uuid.pElems); |
| 792 } | 792 } |
| 793 filter->Release(); | 793 filter->Release(); |
| 794 return 0; | 794 return 0; |
| 795 } | 795 } |
| 796 } // namespace videocapturemodule | 796 } // namespace videocapturemodule |
| 797 } // namespace webrtc | 797 } // namespace webrtc |
| OLD | NEW |