1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Use of this source code is governed by a BSD-style license 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * that can be found in the LICENSE file in the root of the source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * tree. An additional intellectual property rights grant can be found 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * in the file PATENTS. All contributing project authors may 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1187c29b570711208c5f74bf9eaffbea549de866c7pbos@webrtc.org#include "webrtc/modules/video_capture/windows/device_info_ds.h" 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1387c29b570711208c5f74bf9eaffbea549de866c7pbos@webrtc.org#include "webrtc/modules/video_capture/video_capture_config.h" 1487c29b570711208c5f74bf9eaffbea549de866c7pbos@webrtc.org#include "webrtc/modules/video_capture/video_capture_delay.h" 1587c29b570711208c5f74bf9eaffbea549de866c7pbos@webrtc.org#include "webrtc/modules/video_capture/windows/help_functions_ds.h" 1687c29b570711208c5f74bf9eaffbea549de866c7pbos@webrtc.org#include "webrtc/system_wrappers/interface/ref_count.h" 1787c29b570711208c5f74bf9eaffbea549de866c7pbos@webrtc.org#include "webrtc/system_wrappers/interface/trace.h" 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <Dvdmedia.h> 2087c29b570711208c5f74bf9eaffbea549de866c7pbos@webrtc.org#include <Streams.h> 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace videocapturemodule 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 26f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgconst int32_t NoWindowsCaptureDelays = 1; 270f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.orgconst DelayValues WindowsCaptureDelays[NoWindowsCaptureDelays] = { 280f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org "Microsoft LifeCam Cinema", 290f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org "usb#vid_045e&pid_075d", 300f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org { 310f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org {640,480,125}, 320f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org {640,360,117}, 330f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org {424,240,111}, 340f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org {352,288,111}, 350f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org {320,240,116}, 360f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org {176,144,101}, 370f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org {160,120,109}, 380f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org {1280,720,166}, 390f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org {960,544,126}, 400f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org {800,448,120}, 410f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org {800,600,127} 420f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org }, 430f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org}; 440f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org 450f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org// static 46f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgDeviceInfoDS* DeviceInfoDS::Create(const int32_t id) 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 480f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org DeviceInfoDS* dsInfo = new DeviceInfoDS(id); 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!dsInfo || dsInfo->Init() != 0) 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org delete dsInfo; 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org dsInfo = NULL; 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return dsInfo; 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 57f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgDeviceInfoDS::DeviceInfoDS(const int32_t id) 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : DeviceInfoImpl(id), _dsDevEnum(NULL), _dsMonikerDevEnum(NULL), 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _CoUninitializeIsRequired(true) 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // 1) Initialize the COM library (make Windows load the DLLs). 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // CoInitializeEx must be called at least once, and is usually called only once, 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // for each thread that uses the COM library. Multiple calls to CoInitializeEx 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // by the same thread are allowed as long as they pass the same concurrency flag, 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // but subsequent valid calls return S_FALSE. 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // To close the COM library gracefully on a thread, each successful call to 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // CoInitializeEx, including any call that returns S_FALSE, must be balanced 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // by a corresponding call to CoUninitialize. 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /*Apartment-threading, while allowing for multiple threads of execution, 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org serializes all incoming calls by requiring that calls to methods of objects created by this thread always run on the same thread 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org the apartment/thread that created them. In addition, calls can arrive only at message-queue boundaries (i.e., only during a 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org PeekMessage, SendMessage, DispatchMessage, etc.). Because of this serialization, it is not typically necessary to write concurrency control into 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org the code for the object, other than to avoid calls to PeekMessage and SendMessage during processing that must not be interrupted by other method 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org invocations or calls to other objects in the same apartment/thread.*/ 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 79d6f6ff0da2180d5964e733ba8205c1a3353872c4henrika@webrtc.org ///CoInitializeEx(NULL, COINIT_APARTMENTTHREADED ); //| COINIT_SPEED_OVER_MEMORY 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); // Use COINIT_MULTITHREADED since Voice Engine uses COINIT_MULTITHREADED 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (FAILED(hr)) 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Avoid calling CoUninitialize() since CoInitializeEx() failed. 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _CoUninitializeIsRequired = FALSE; 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (hr == RPC_E_CHANGED_MODE) 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Calling thread has already initialized COM to be used in a single-threaded 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // apartment (STA). We are then prevented from using STA. 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Details: hr = 0x80010106 <=> "Cannot change thread mode after it is set". 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id, 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "VideoCaptureWindowsDSInfo::VideoCaptureWindowsDSInfo " 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) => " 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "RPC_E_CHANGED_MODE, error 0x%x", 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr); 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1010f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.orgDeviceInfoDS::~DeviceInfoDS() 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(_dsMonikerDevEnum); 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(_dsDevEnum); 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (_CoUninitializeIsRequired) 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CoUninitialize(); 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 111f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgint32_t DeviceInfoDS::Init() 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org IID_ICreateDevEnum, (void **) &_dsDevEnum); 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (hr != NOERROR) 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Failed to create CLSID_SystemDeviceEnum, error 0x%x", hr); 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 123f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orguint32_t DeviceInfoDS::NumberOfDevices() 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ReadLockScoped cs(_apiLock); 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return GetDeviceInfo(0, 0, 0, 0, 0, 0, 0); 1273b7f2ab86f3d03989abdaff7091f83cddaf26aedtommi@webrtc.org} 1280f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org 129f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgint32_t DeviceInfoDS::GetDeviceName( 130f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org uint32_t deviceNumber, 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char* deviceNameUTF8, 132f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org uint32_t deviceNameLength, 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char* deviceUniqueIdUTF8, 134f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org uint32_t deviceUniqueIdUTF8Length, 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char* productUniqueIdUTF8, 136f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org uint32_t productUniqueIdUTF8Length) 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ReadLockScoped cs(_apiLock); 139f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org const int32_t result = GetDeviceInfo(deviceNumber, deviceNameUTF8, 140f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org deviceNameLength, 141f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org deviceUniqueIdUTF8, 142f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org deviceUniqueIdUTF8Length, 143f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org productUniqueIdUTF8, 144f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org productUniqueIdUTF8Length); 145f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org return result > (int32_t) deviceNumber ? 0 : -1; 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 148f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgint32_t DeviceInfoDS::GetDeviceInfo( 149f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org uint32_t deviceNumber, 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char* deviceNameUTF8, 151f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org uint32_t deviceNameLength, 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char* deviceUniqueIdUTF8, 153f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org uint32_t deviceUniqueIdUTF8Length, 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char* productUniqueIdUTF8, 155f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org uint32_t productUniqueIdUTF8Length) 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // enumerate all video capture devices 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(_dsMonikerDevEnum); 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org HRESULT hr = 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _dsDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &_dsMonikerDevEnum, 0); 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (hr != NOERROR) 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Failed to enumerate CLSID_SystemDeviceEnum, error 0x%x." 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " No webcam exist?", hr); 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _dsMonikerDevEnum->Reset(); 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ULONG cFetched; 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org IMoniker *pM; 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int index = 0; 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (S_OK == _dsMonikerDevEnum->Next(1, &pM, &cFetched)) 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org IPropertyBag *pBag; 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **) &pBag); 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (S_OK == hr) 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Find the description or friendly name. 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VARIANT varName; 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VariantInit(&varName); 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = pBag->Read(L"Description", &varName, 0); 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (FAILED(hr)) 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = pBag->Read(L"FriendlyName", &varName, 0); 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (SUCCEEDED(hr)) 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // ignore all VFW drivers 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if ((wcsstr(varName.bstrVal, (L"(VFW)")) == NULL) && 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (_wcsnicmp(varName.bstrVal, (L"Google Camera Adapter"),21) 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org != 0)) 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 197d6f6ff0da2180d5964e733ba8205c1a3353872c4henrika@webrtc.org // Found a valid device. 198d6f6ff0da2180d5964e733ba8205c1a3353872c4henrika@webrtc.org if (index == static_cast<int>(deviceNumber)) 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int convResult = 0; 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (deviceNameLength > 0) 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org convResult = WideCharToMultiByte(CP_UTF8, 0, 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org varName.bstrVal, -1, 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (char*) deviceNameUTF8, 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceNameLength, NULL, 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org NULL); 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (convResult == 0) 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::kTraceVideoCapture, _id, 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Failed to convert device name to UTF8. %d", 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GetLastError()); 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (deviceUniqueIdUTF8Length > 0) 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = pBag->Read(L"DevicePath", &varName, 0); 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (FAILED(hr)) 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org strncpy_s((char *) deviceUniqueIdUTF8, 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceUniqueIdUTF8Length, 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (char *) deviceNameUTF8, convResult); 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::kTraceVideoCapture, _id, 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Failed to get deviceUniqueIdUTF8 using deviceNameUTF8"); 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org convResult = WideCharToMultiByte( 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CP_UTF8, 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0, 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org varName.bstrVal, 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org -1, 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (char*) deviceUniqueIdUTF8, 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceUniqueIdUTF8Length, 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org NULL, NULL); 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (convResult == 0) 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::kTraceVideoCapture, _id, 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Failed to convert device name to UTF8. %d", 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GetLastError()); 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (productUniqueIdUTF8 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org && productUniqueIdUTF8Length > 0) 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GetProductId(deviceUniqueIdUTF8, 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org productUniqueIdUTF8, 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org productUniqueIdUTF8Length); 253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ++index; // increase the number of valid devices 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VariantClear(&varName); 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pBag->Release(); 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pM->Release(); 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (deviceNameLength) 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id, "%s %s", 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org __FUNCTION__, deviceNameUTF8); 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return index; 273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 2750f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.orgIBaseFilter * DeviceInfoDS::GetDeviceFilter( 276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const char* deviceUniqueIdUTF8, 277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char* productUniqueIdUTF8, 278f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org uint32_t productUniqueIdUTF8Length) 279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 281f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org const int32_t deviceUniqueIdUTF8Length = 282f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org (int32_t) strlen((char*) deviceUniqueIdUTF8); // UTF8 is also NULL terminated 283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (deviceUniqueIdUTF8Length > kVideoCaptureUniqueNameLength) 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Device name too long"); 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return NULL; 288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // enumerate all video capture devices 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(_dsMonikerDevEnum); 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org HRESULT hr = _dsDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &_dsMonikerDevEnum, 0); 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (hr != NOERROR) 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Failed to enumerate CLSID_SystemDeviceEnum, error 0x%x." 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " No webcam exist?", hr); 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _dsMonikerDevEnum->Reset(); 302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ULONG cFetched; 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org IMoniker *pM; 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org IBaseFilter *captureFilter = NULL; 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool deviceFound = false; 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (S_OK == _dsMonikerDevEnum->Next(1, &pM, &cFetched) && !deviceFound) 308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org IPropertyBag *pBag; 310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **) &pBag); 311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (S_OK == hr) 312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Find the description or friendly name. 314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VARIANT varName; 315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VariantInit(&varName); 316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (deviceUniqueIdUTF8Length > 0) 317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = pBag->Read(L"DevicePath", &varName, 0); 319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (FAILED(hr)) 320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = pBag->Read(L"Description", &varName, 0); 322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (FAILED(hr)) 323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = pBag->Read(L"FriendlyName", &varName, 0); 325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (SUCCEEDED(hr)) 328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char tempDevicePathUTF8[256]; 330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tempDevicePathUTF8[0] = 0; 331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WideCharToMultiByte(CP_UTF8, 0, varName.bstrVal, -1, 332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tempDevicePathUTF8, 333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org sizeof(tempDevicePathUTF8), NULL, 334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org NULL); 335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (strncmp(tempDevicePathUTF8, 336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (const char*) deviceUniqueIdUTF8, 337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceUniqueIdUTF8Length) == 0) 338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 339d6f6ff0da2180d5964e733ba8205c1a3353872c4henrika@webrtc.org // We have found the requested device 340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceFound = true; 341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = pM->BindToObject(0, 0, IID_IBaseFilter, 342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (void**) &captureFilter); 343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if FAILED(hr) 344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _id, "Failed to bind to the selected capture device %d",hr); 347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (productUniqueIdUTF8 350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org && productUniqueIdUTF8Length > 0) // Get the device name 351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GetProductId(deviceUniqueIdUTF8, 354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org productUniqueIdUTF8, 355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org productUniqueIdUTF8Length); 356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VariantClear(&varName); 362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pBag->Release(); 363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pM->Release(); 364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return captureFilter; 367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 369f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgint32_t DeviceInfoDS::GetWindowsCapability( 37052c5c708de6f5bcf9c2a58cece45013aa5efacd7pbos@webrtc.org const int32_t capabilityIndex, 37152c5c708de6f5bcf9c2a58cece45013aa5efacd7pbos@webrtc.org VideoCaptureCapabilityWindows& windowsCapability) { 37252c5c708de6f5bcf9c2a58cece45013aa5efacd7pbos@webrtc.org ReadLockScoped cs(_apiLock); 37352c5c708de6f5bcf9c2a58cece45013aa5efacd7pbos@webrtc.org 37479c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org if (capabilityIndex < 0 || static_cast<size_t>(capabilityIndex) >= 37579c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org _captureCapabilitiesWindows.size()) { 37652c5c708de6f5bcf9c2a58cece45013aa5efacd7pbos@webrtc.org return -1; 37779c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org } 37852c5c708de6f5bcf9c2a58cece45013aa5efacd7pbos@webrtc.org 37979c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org windowsCapability = _captureCapabilitiesWindows[capabilityIndex]; 38052c5c708de6f5bcf9c2a58cece45013aa5efacd7pbos@webrtc.org return 0; 381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 383f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgint32_t DeviceInfoDS::CreateCapabilityMap( 384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const char* deviceUniqueIdUTF8) 385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Reset old capability list 38852c5c708de6f5bcf9c2a58cece45013aa5efacd7pbos@webrtc.org _captureCapabilities.clear(); 38952c5c708de6f5bcf9c2a58cece45013aa5efacd7pbos@webrtc.org 390f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org const int32_t deviceUniqueIdUTF8Length = 391f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org (int32_t) strlen((char*) deviceUniqueIdUTF8); 392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (deviceUniqueIdUTF8Length > kVideoCaptureUniqueNameLength) 393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, 395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Device name too long"); 396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id, 399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "CreateCapabilityMap called for device %s", deviceUniqueIdUTF8); 400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char productId[kVideoCaptureProductIdLength]; 4030f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org IBaseFilter* captureDevice = DeviceInfoDS::GetDeviceFilter( 404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org deviceUniqueIdUTF8, 405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org productId, 406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org kVideoCaptureProductIdLength); 407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!captureDevice) 408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 4090f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.org IPin* outputCapturePin = GetOutputPin(captureDevice, GUID_NULL); 410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!outputCapturePin) 411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, 413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Failed to get capture device output pin"); 414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(captureDevice); 415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org IAMExtDevice* extDevice = NULL; 418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org HRESULT hr = captureDevice->QueryInterface(IID_IAMExtDevice, 419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (void **) &extDevice); 420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (SUCCEEDED(hr) && extDevice) 421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id, 423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "This is an external device"); 424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org extDevice->Release(); 425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org IAMStreamConfig* streamConfig = NULL; 428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = outputCapturePin->QueryInterface(IID_IAMStreamConfig, 429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (void**) &streamConfig); 430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (FAILED(hr)) 431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, 433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Failed to get IID_IAMStreamConfig interface from capture device"); 434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // this gets the FPS 438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org IAMVideoControl* videoControlConfig = NULL; 439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org HRESULT hrVC = captureDevice->QueryInterface(IID_IAMVideoControl, 440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (void**) &videoControlConfig); 441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (FAILED(hrVC)) 442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id, 444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "IID_IAMVideoControl Interface NOT SUPPORTED"); 445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org AM_MEDIA_TYPE *pmt = NULL; 448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VIDEO_STREAM_CONFIG_CAPS caps; 449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int count, size; 450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = streamConfig->GetNumberOfCapabilities(&count, &size); 452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (FAILED(hr)) 453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, 455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Failed to GetNumberOfCapabilities"); 456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(videoControlConfig); 457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(streamConfig); 458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(outputCapturePin); 459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(captureDevice); 460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 463d6f6ff0da2180d5964e733ba8205c1a3353872c4henrika@webrtc.org // Check if the device support formattype == FORMAT_VideoInfo2 and FORMAT_VideoInfo. 464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Prefer FORMAT_VideoInfo since some cameras (ZureCam) has been seen having problem with MJPEG and FORMAT_VideoInfo2 465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Interlace flag is only supported in FORMAT_VideoInfo2 466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool supportFORMAT_VideoInfo2 = false; 467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool supportFORMAT_VideoInfo = false; 468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool foundInterlacedFormat = false; 469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org GUID preferedVideoFormat = FORMAT_VideoInfo; 470f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org for (int32_t tmp = 0; tmp < count; ++tmp) 471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = streamConfig->GetStreamCaps(tmp, &pmt, 473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org reinterpret_cast<BYTE*> (&caps)); 474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!FAILED(hr)) 475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (pmt->majortype == MEDIATYPE_Video 477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org && pmt->formattype == FORMAT_VideoInfo2) 478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id, 480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " Device support FORMAT_VideoInfo2"); 481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org supportFORMAT_VideoInfo2 = true; 482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VIDEOINFOHEADER2* h = 483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org reinterpret_cast<VIDEOINFOHEADER2*> (pmt->pbFormat); 484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(h); 485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org foundInterlacedFormat |= h->dwInterlaceFlags 486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org & (AMINTERLACE_IsInterlaced 487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org | AMINTERLACE_DisplayModeBobOnly); 488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (pmt->majortype == MEDIATYPE_Video 490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org && pmt->formattype == FORMAT_VideoInfo) 491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideoCapture, _id, 493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org " Device support FORMAT_VideoInfo2"); 494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org supportFORMAT_VideoInfo = true; 495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (supportFORMAT_VideoInfo2) 499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (supportFORMAT_VideoInfo && !foundInterlacedFormat) 501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org preferedVideoFormat = FORMAT_VideoInfo; 503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org preferedVideoFormat = FORMAT_VideoInfo2; 507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 510f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org for (int32_t tmp = 0; tmp < count; ++tmp) 511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = streamConfig->GetStreamCaps(tmp, &pmt, 513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org reinterpret_cast<BYTE*> (&caps)); 514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (FAILED(hr)) 515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id, 517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Failed to GetStreamCaps"); 518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(videoControlConfig); 519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(streamConfig); 520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(outputCapturePin); 521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(captureDevice); 522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (pmt->majortype == MEDIATYPE_Video 526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org && pmt->formattype == preferedVideoFormat) 527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 52979c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org VideoCaptureCapabilityWindows capability; 530f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org int64_t avgTimePerFrame = 0; 531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (pmt->formattype == FORMAT_VideoInfo) 533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VIDEOINFOHEADER* h = 535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org reinterpret_cast<VIDEOINFOHEADER*> (pmt->pbFormat); 536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(h); 53779c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.directShowCapabilityIndex = tmp; 53879c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.width = h->bmiHeader.biWidth; 53979c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.height = h->bmiHeader.biHeight; 540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org avgTimePerFrame = h->AvgTimePerFrame; 541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (pmt->formattype == FORMAT_VideoInfo2) 543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org VIDEOINFOHEADER2* h = 545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org reinterpret_cast<VIDEOINFOHEADER2*> (pmt->pbFormat); 546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org assert(h); 54779c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.directShowCapabilityIndex = tmp; 54879c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.width = h->bmiHeader.biWidth; 54979c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.height = h->bmiHeader.biHeight; 55079c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.interlaced = h->dwInterlaceFlags 551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org & (AMINTERLACE_IsInterlaced 552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org | AMINTERLACE_DisplayModeBobOnly); 553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org avgTimePerFrame = h->AvgTimePerFrame; 554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (hrVC == S_OK) 557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 55827329e94a66f2799d299c044933e59b64a4b9578vikasmarwaha@webrtc.org LONGLONG *frameDurationList; 55979c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org LONGLONG maxFPS; 560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org long listSize; 561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SIZE size; 56279c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org size.cx = capability.width; 56379c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org size.cy = capability.height; 564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // GetMaxAvailableFrameRate doesn't return max frame rate always 566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // eg: Logitech Notebook. This may be due to a bug in that API 567d6f6ff0da2180d5964e733ba8205c1a3353872c4henrika@webrtc.org // because GetFrameRateList array is reversed in the above camera. So 568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // a util method written. Can't assume the first value will return 569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // the max fps. 570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hrVC = videoControlConfig->GetFrameRateList(outputCapturePin, 571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tmp, size, 572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &listSize, 57327329e94a66f2799d299c044933e59b64a4b9578vikasmarwaha@webrtc.org &frameDurationList); 574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 57527329e94a66f2799d299c044933e59b64a4b9578vikasmarwaha@webrtc.org // On some odd cameras, you may get a 0 for duration. 57627329e94a66f2799d299c044933e59b64a4b9578vikasmarwaha@webrtc.org // GetMaxOfFrameArray returns the lowest duration (highest FPS) 57727329e94a66f2799d299c044933e59b64a4b9578vikasmarwaha@webrtc.org if (hrVC == S_OK && listSize > 0 && 57879c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org 0 != (maxFPS = GetMaxOfFrameArray(frameDurationList, 57927329e94a66f2799d299c044933e59b64a4b9578vikasmarwaha@webrtc.org listSize))) 580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 58179c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.maxFPS = static_cast<int> (10000000 582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org / maxFPS); 58379c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.supportFrameRateControl = true; 584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else // use existing method 586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _id, 589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "GetMaxAvailableFrameRate NOT SUPPORTED"); 590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (avgTimePerFrame > 0) 59179c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.maxFPS = static_cast<int> (10000000 592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org / avgTimePerFrame); 593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 59479c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.maxFPS = 0; 595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else // use existing method in case IAMVideoControl is not supported 598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 599b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (avgTimePerFrame > 0) 60079c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.maxFPS = static_cast<int> (10000000 601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org / avgTimePerFrame); 602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 60379c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.maxFPS = 0; 604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // can't switch MEDIATYPE :~( 607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (pmt->subtype == MEDIASUBTYPE_I420) 608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 60979c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.rawType = kVideoI420; 610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (pmt->subtype == MEDIASUBTYPE_IYUV) 612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 61379c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.rawType = kVideoIYUV; 614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (pmt->subtype == MEDIASUBTYPE_RGB24) 616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 61779c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.rawType = kVideoRGB24; 618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (pmt->subtype == MEDIASUBTYPE_YUY2) 620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 62179c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.rawType = kVideoYUY2; 622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (pmt->subtype == MEDIASUBTYPE_RGB565) 624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 62579c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.rawType = kVideoRGB565; 626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (pmt->subtype == MEDIASUBTYPE_MJPG) 628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 62979c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.rawType = kVideoMJPEG; 630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (pmt->subtype == MEDIASUBTYPE_dvsl 632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org || pmt->subtype == MEDIASUBTYPE_dvsd 633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org || pmt->subtype == MEDIASUBTYPE_dvhd) // If this is an external DV camera 634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 63579c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.rawType = kVideoYUY2;// MS DV filter seems to create this type 636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (pmt->subtype == MEDIASUBTYPE_UYVY) // Seen used by Declink capture cards 638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 63979c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.rawType = kVideoUYVY; 640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else if (pmt->subtype == MEDIASUBTYPE_HDYC) // Seen used by Declink capture cards. Uses BT. 709 color. Not entiry correct to use UYVY. http://en.wikipedia.org/wiki/YCbCr 642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, _id, 644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Device support HDYC."); 64579c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.rawType = kVideoUYVY; 646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WCHAR strGuid[39]; 650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org StringFromGUID2(pmt->subtype, strGuid, 39); 651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE( webrtc::kTraceWarning, 652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org webrtc::kTraceVideoCapture, _id, 653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Device support unknown media type %ls, width %d, height %d", 654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org strGuid); 655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org continue; 656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Get the expected capture delay from the static list 65979c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.expectedCaptureDelay 660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org = GetExpectedCaptureDelay(WindowsCaptureDelays, 661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org NoWindowsCaptureDelays, 662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org productId, 66379c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.width, 66479c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.height); 66579c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org _captureCapabilities.push_back(capability); 66679c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org _captureCapabilitiesWindows.push_back(capability); 667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE( webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id, 668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Camera capability, width:%d height:%d type:%d fps:%d", 66979c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.width, capability.height, 67079c884c86807f45d9629b75b75261e9bc239643efischman@webrtc.org capability.rawType, capability.maxFPS); 671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org DeleteMediaType(pmt); 673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pmt = NULL; 674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(streamConfig); 676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(videoControlConfig); 677b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(outputCapturePin); 678b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org RELEASE_AND_CLEAR(captureDevice); // Release the capture device 679d6f6ff0da2180d5964e733ba8205c1a3353872c4henrika@webrtc.org 680b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Store the new used device name 681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _lastUsedDeviceNameLength = deviceUniqueIdUTF8Length; 682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _lastUsedDeviceName = (char*) realloc(_lastUsedDeviceName, 683b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org _lastUsedDeviceNameLength 684b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org + 1); 685b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memcpy(_lastUsedDeviceName, deviceUniqueIdUTF8, _lastUsedDeviceNameLength+ 1); 686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideoCapture, _id, 68752c5c708de6f5bcf9c2a58cece45013aa5efacd7pbos@webrtc.org "CreateCapabilityMap %d", _captureCapabilities.size()); 688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 68952c5c708de6f5bcf9c2a58cece45013aa5efacd7pbos@webrtc.org return static_cast<int32_t>(_captureCapabilities.size()); 690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 692d6f6ff0da2180d5964e733ba8205c1a3353872c4henrika@webrtc.org/* Constructs a product ID from the Windows DevicePath. on a USB device the devicePath contains product id and vendor id. 693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org This seems to work for firewire as well 694b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Example of device path 695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "\\?\usb#vid_0408&pid_2010&mi_00#7&258e7aaf&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global" 696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "\\?\avc#sony&dv-vcr&camcorder&dv#65b2d50301460008#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global" 697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 6980f224ffecd2f1190744b5bc5c97f4ce373ba0adetommi@webrtc.orgvoid DeviceInfoDS::GetProductId(const char* devicePath, 699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char* productUniqueIdUTF8, 700f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org uint32_t productUniqueIdUTF8Length) 701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *productUniqueIdUTF8 = '\0'; 703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char* startPos = strstr((char*) devicePath, "\\\\?\\"); 704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!startPos) 705b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org strncpy_s((char*) productUniqueIdUTF8, productUniqueIdUTF8Length, "", 1); 707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1, 708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Failed to get the product Id"); 709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org startPos += 4; 712b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 713b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org char* pos = strchr(startPos, '&'); 714b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!pos || pos >= (char*) devicePath + strlen((char*) devicePath)) 715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org strncpy_s((char*) productUniqueIdUTF8, productUniqueIdUTF8Length, "", 1); 717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1, 718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Failed to get the product Id"); 719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 7215c247c45aa8b51e3504cf0455e92b6704ab63fdbtommi@webrtc.org // Find the second occurrence. 722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org pos = strchr(pos + 1, '&'); 723f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org uint32_t bytesToCopy = (uint32_t)(pos - startPos); 724b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (pos && (bytesToCopy <= productUniqueIdUTF8Length) && bytesToCopy 725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org <= kVideoCaptureProductIdLength) 726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org strncpy_s((char*) productUniqueIdUTF8, productUniqueIdUTF8Length, 728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (char*) startPos, bytesToCopy); 729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else 731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org strncpy_s((char*) productUniqueIdUTF8, productUniqueIdUTF8Length, "", 1); 733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, -1, 734b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org "Failed to get the product Id"); 735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 736b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 737b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 738f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.orgint32_t DeviceInfoDS::DisplayCaptureSettingsDialogBox( 739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const char* deviceUniqueIdUTF8, 740b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const char* dialogTitleUTF8, 741b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org void* parentWindow, 742f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org uint32_t positionX, 743f7e44d647cd0f893a185dfbe043cb313cab29fd0pbos@webrtc.org uint32_t positionY) 744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{ 745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ReadLockScoped cs(_apiLock); 746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org HWND window = (HWND) parentWindow; 747b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 748b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org IBaseFilter* filter = GetDeviceFilter(deviceUniqueIdUTF8, NULL, 0); 749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!filter) 750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ISpecifyPropertyPages* pPages = NULL; 753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CAUUID uuid; 754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org HRESULT hr = S_OK; 755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = filter->QueryInterface(IID_ISpecifyPropertyPages, (LPVOID*) &pPages); 757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!SUCCEEDED(hr)) 758b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org filter->Release(); 760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 762b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = pPages->GetPages(&uuid); 763b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!SUCCEEDED(hr)) 764b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 765b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org filter->Release(); 766b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 767b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 768b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 769b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org WCHAR tempDialogTitleWide[256]; 770b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tempDialogTitleWide[0] = 0; 771b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int size = 255; 772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // UTF-8 to wide char 774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org MultiByteToWideChar(CP_UTF8, 0, (char*) dialogTitleUTF8, -1, 775b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tempDialogTitleWide, size); 776b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 777b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Invoke a dialog box to display. 778b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 779b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org hr = OleCreatePropertyFrame(window, // You must create the parent window. 780b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org positionX, // Horizontal position for the dialog box. 781b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org positionY, // Vertical position for the dialog box. 782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org tempDialogTitleWide,// String used for the dialog box caption. 783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 1, // Number of pointers passed in pPlugin. 784b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (LPUNKNOWN*) &filter, // Pointer to the filter. 785b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uuid.cElems, // Number of property pages. 786b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org uuid.pElems, // Array of property page CLSIDs. 787b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LOCALE_USER_DEFAULT, // Locale ID for the dialog box. 788b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 0, NULL); // Reserved 789b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Release memory. 790b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (uuid.pElems) 791b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org { 792b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org CoTaskMemFree(uuid.pElems); 793b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 794b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org filter->Release(); 795b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 796b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 7973b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org} // namespace videocapturemodule 7983b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org} // namespace webrtc 799