| Index: webrtc/modules/video_capture/windows/device_info_ds.cc
|
| diff --git a/webrtc/modules/video_capture/windows/device_info_ds.cc b/webrtc/modules/video_capture/windows/device_info_ds.cc
|
| index 0b704abe954caa86038a96b81fbfa44f9fc0410a..2a177083c4b29fdb21f1e8549b13646b8a6ba23e 100644
|
| --- a/webrtc/modules/video_capture/windows/device_info_ds.cc
|
| +++ b/webrtc/modules/video_capture/windows/device_info_ds.cc
|
| @@ -48,53 +48,63 @@ DeviceInfoDS* DeviceInfoDS::Create()
|
| if (!dsInfo || dsInfo->Init() != 0)
|
| {
|
| delete dsInfo;
|
| - dsInfo = NULL;
|
| + dsInfo = nullptr;
|
| }
|
| return dsInfo;
|
| }
|
|
|
| DeviceInfoDS::DeviceInfoDS()
|
| - : _dsDevEnum(NULL), _dsMonikerDevEnum(NULL),
|
| - _CoUninitializeIsRequired(true)
|
| -{
|
| - // 1) Initialize the COM library (make Windows load the DLLs).
|
| - //
|
| - // CoInitializeEx must be called at least once, and is usually called only once,
|
| - // for each thread that uses the COM library. Multiple calls to CoInitializeEx
|
| - // by the same thread are allowed as long as they pass the same concurrency flag,
|
| - // but subsequent valid calls return S_FALSE.
|
| - // To close the COM library gracefully on a thread, each successful call to
|
| - // CoInitializeEx, including any call that returns S_FALSE, must be balanced
|
| - // by a corresponding call to CoUninitialize.
|
| - //
|
| -
|
| - /*Apartment-threading, while allowing for multiple threads of execution,
|
| - serializes all incoming calls by requiring that calls to methods of objects created by this thread always run on the same thread
|
| - the apartment/thread that created them. In addition, calls can arrive only at message-queue boundaries (i.e., only during a
|
| - PeekMessage, SendMessage, DispatchMessage, etc.). Because of this serialization, it is not typically necessary to write concurrency control into
|
| - the code for the object, other than to avoid calls to PeekMessage and SendMessage during processing that must not be interrupted by other method
|
| - invocations or calls to other objects in the same apartment/thread.*/
|
| -
|
| - ///CoInitializeEx(NULL, COINIT_APARTMENTTHREADED ); //| COINIT_SPEED_OVER_MEMORY
|
| - HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); // Use COINIT_MULTITHREADED since Voice Engine uses COINIT_MULTITHREADED
|
| - if (FAILED(hr))
|
| - {
|
| - // Avoid calling CoUninitialize() since CoInitializeEx() failed.
|
| - _CoUninitializeIsRequired = FALSE;
|
| -
|
| - if (hr == RPC_E_CHANGED_MODE)
|
| - {
|
| - // Calling thread has already initialized COM to be used in a single-threaded
|
| - // apartment (STA). We are then prevented from using STA.
|
| - // Details: hr = 0x80010106 <=> "Cannot change thread mode after it is set".
|
| - //
|
| - WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, 0,
|
| - "VideoCaptureWindowsDSInfo::VideoCaptureWindowsDSInfo "
|
| - "CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) => "
|
| - "RPC_E_CHANGED_MODE, error 0x%x",
|
| - hr);
|
| - }
|
| + : _dsDevEnum(nullptr),
|
| + _dsMonikerDevEnum(nullptr),
|
| + _CoUninitializeIsRequired(true) {
|
| + // 1) Initialize the COM library (make Windows load the DLLs).
|
| + //
|
| + // CoInitializeEx must be called at least once, and is usually called only
|
| + // once,
|
| + // for each thread that uses the COM library. Multiple calls to CoInitializeEx
|
| + // by the same thread are allowed as long as they pass the same concurrency
|
| + // flag,
|
| + // but subsequent valid calls return S_FALSE.
|
| + // To close the COM library gracefully on a thread, each successful call to
|
| + // CoInitializeEx, including any call that returns S_FALSE, must be balanced
|
| + // by a corresponding call to CoUninitialize.
|
| + //
|
| +
|
| + /*Apartment-threading, while allowing for multiple threads of execution,
|
| + serializes all incoming calls by requiring that calls to methods of objects
|
| + created by this thread always run on the same thread
|
| + the apartment/thread that created them. In addition, calls can arrive only at
|
| + message-queue boundaries (i.e., only during a
|
| + PeekMessage, SendMessage, DispatchMessage, etc.). Because of this
|
| + serialization, it is not typically necessary to write concurrency control
|
| + into
|
| + the code for the object, other than to avoid calls to PeekMessage and
|
| + SendMessage during processing that must not be interrupted by other method
|
| + invocations or calls to other objects in the same apartment/thread.*/
|
| +
|
| + /// CoInitializeEx(null, COINIT_APARTMENTTHREADED ); //|
|
| + /// COINIT_SPEED_OVER_MEMORY
|
| + HRESULT hr = CoInitializeEx(
|
| + nullptr, COINIT_MULTITHREADED); // Use COINIT_MULTITHREADED since Voice
|
| + // Engine uses COINIT_MULTITHREADED
|
| + if (FAILED(hr)) {
|
| + // Avoid calling CoUninitialize() since CoInitializeEx() failed.
|
| + _CoUninitializeIsRequired = FALSE;
|
| +
|
| + if (hr == RPC_E_CHANGED_MODE) {
|
| + // Calling thread has already initialized COM to be used in a
|
| + // single-threaded
|
| + // apartment (STA). We are then prevented from using STA.
|
| + // Details: hr = 0x80010106 <=> "Cannot change thread mode after it is
|
| + // set".
|
| + //
|
| + WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideoCapture, 0,
|
| + "VideoCaptureWindowsDSInfo::VideoCaptureWindowsDSInfo "
|
| + "CoInitializeEx(null, COINIT_APARTMENTTHREADED) => "
|
| + "RPC_E_CHANGED_MODE, error 0x%x",
|
| + hr);
|
| }
|
| + }
|
| }
|
|
|
| DeviceInfoDS::~DeviceInfoDS()
|
| @@ -109,13 +119,12 @@ DeviceInfoDS::~DeviceInfoDS()
|
|
|
| int32_t DeviceInfoDS::Init()
|
| {
|
| - HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
|
| - IID_ICreateDevEnum, (void **) &_dsDevEnum);
|
| - if (hr != NOERROR)
|
| - {
|
| - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0,
|
| - "Failed to create CLSID_SystemDeviceEnum, error 0x%x", hr);
|
| - return -1;
|
| + HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr, CLSCTX_INPROC,
|
| + IID_ICreateDevEnum, (void**)&_dsDevEnum);
|
| + if (hr != NOERROR) {
|
| + WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0,
|
| + "Failed to create CLSID_SystemDeviceEnum, error 0x%x", hr);
|
| + return -1;
|
| }
|
| return 0;
|
| }
|
| @@ -189,72 +198,56 @@ int32_t DeviceInfoDS::GetDeviceInfo(
|
| if (SUCCEEDED(hr))
|
| {
|
| // ignore all VFW drivers
|
| - if ((wcsstr(varName.bstrVal, (L"(VFW)")) == NULL) &&
|
| - (_wcsnicmp(varName.bstrVal, (L"Google Camera Adapter"),21)
|
| - != 0))
|
| - {
|
| - // Found a valid device.
|
| - if (index == static_cast<int>(deviceNumber))
|
| - {
|
| - int convResult = 0;
|
| - if (deviceNameLength > 0)
|
| - {
|
| - convResult = WideCharToMultiByte(CP_UTF8, 0,
|
| - varName.bstrVal, -1,
|
| - (char*) deviceNameUTF8,
|
| - deviceNameLength, NULL,
|
| - NULL);
|
| - if (convResult == 0)
|
| - {
|
| - WEBRTC_TRACE(webrtc::kTraceError,
|
| - webrtc::kTraceVideoCapture, 0,
|
| - "Failed to convert device name to UTF8. %d",
|
| - GetLastError());
|
| - return -1;
|
| - }
|
| + if ((wcsstr(varName.bstrVal, (L"(VFW)")) == nullptr) &&
|
| + (_wcsnicmp(varName.bstrVal, (L"Google Camera Adapter"),
|
| + 21) != 0)) {
|
| + // Found a valid device.
|
| + if (index == static_cast<int>(deviceNumber)) {
|
| + int convResult = 0;
|
| + if (deviceNameLength > 0) {
|
| + convResult = WideCharToMultiByte(
|
| + CP_UTF8, 0, varName.bstrVal, -1,
|
| + (char*)deviceNameUTF8, deviceNameLength, nullptr,
|
| + nullptr);
|
| + if (convResult == 0) {
|
| + WEBRTC_TRACE(
|
| + webrtc::kTraceError, webrtc::kTraceVideoCapture, 0,
|
| + "Failed to convert device name to UTF8. %d",
|
| + GetLastError());
|
| + return -1;
|
| + }
|
| + }
|
| + if (deviceUniqueIdUTF8Length > 0) {
|
| + hr = pBag->Read(L"DevicePath", &varName, 0);
|
| + if (FAILED(hr)) {
|
| + strncpy_s((char*)deviceUniqueIdUTF8,
|
| + deviceUniqueIdUTF8Length,
|
| + (char*)deviceNameUTF8, convResult);
|
| + WEBRTC_TRACE(webrtc::kTraceError,
|
| + webrtc::kTraceVideoCapture, 0,
|
| + "Failed to get deviceUniqueIdUTF8 using "
|
| + "deviceNameUTF8");
|
| + } else {
|
| + convResult = WideCharToMultiByte(
|
| + CP_UTF8, 0, varName.bstrVal, -1,
|
| + (char*)deviceUniqueIdUTF8, deviceUniqueIdUTF8Length,
|
| + nullptr, nullptr);
|
| + if (convResult == 0) {
|
| + WEBRTC_TRACE(
|
| + webrtc::kTraceError, webrtc::kTraceVideoCapture,
|
| + 0, "Failed to convert device name to UTF8. %d",
|
| + GetLastError());
|
| + return -1;
|
| }
|
| - if (deviceUniqueIdUTF8Length > 0)
|
| - {
|
| - hr = pBag->Read(L"DevicePath", &varName, 0);
|
| - if (FAILED(hr))
|
| - {
|
| - strncpy_s((char *) deviceUniqueIdUTF8,
|
| - deviceUniqueIdUTF8Length,
|
| - (char *) deviceNameUTF8, convResult);
|
| - WEBRTC_TRACE(webrtc::kTraceError,
|
| - webrtc::kTraceVideoCapture, 0,
|
| - "Failed to get deviceUniqueIdUTF8 using deviceNameUTF8");
|
| - }
|
| - else
|
| - {
|
| - convResult = WideCharToMultiByte(
|
| - CP_UTF8,
|
| - 0,
|
| - varName.bstrVal,
|
| - -1,
|
| - (char*) deviceUniqueIdUTF8,
|
| - deviceUniqueIdUTF8Length,
|
| - NULL, NULL);
|
| - if (convResult == 0)
|
| - {
|
| - WEBRTC_TRACE(webrtc::kTraceError,
|
| - webrtc::kTraceVideoCapture, 0,
|
| - "Failed to convert device name to UTF8. %d",
|
| - GetLastError());
|
| - return -1;
|
| - }
|
| - if (productUniqueIdUTF8
|
| - && productUniqueIdUTF8Length > 0)
|
| - {
|
| - GetProductId(deviceUniqueIdUTF8,
|
| - productUniqueIdUTF8,
|
| - productUniqueIdUTF8Length);
|
| - }
|
| - }
|
| + if (productUniqueIdUTF8 &&
|
| + productUniqueIdUTF8Length > 0) {
|
| + GetProductId(deviceUniqueIdUTF8, productUniqueIdUTF8,
|
| + productUniqueIdUTF8Length);
|
| }
|
| -
|
| + }
|
| }
|
| - ++index; // increase the number of valid devices
|
| + }
|
| + ++index; // increase the number of valid devices
|
| }
|
| }
|
| VariantClear(&varName);
|
| @@ -277,14 +270,12 @@ IBaseFilter * DeviceInfoDS::GetDeviceFilter(
|
| char* productUniqueIdUTF8,
|
| uint32_t productUniqueIdUTF8Length)
|
| {
|
| -
|
| - const int32_t deviceUniqueIdUTF8Length =
|
| - (int32_t) strlen((char*) deviceUniqueIdUTF8); // UTF8 is also NULL terminated
|
| - if (deviceUniqueIdUTF8Length > kVideoCaptureUniqueNameLength)
|
| - {
|
| - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0,
|
| - "Device name too long");
|
| - return NULL;
|
| + const int32_t deviceUniqueIdUTF8Length = (int32_t)strlen(
|
| + (char*)deviceUniqueIdUTF8); // UTF8 is also nullptr terminated
|
| + if (deviceUniqueIdUTF8Length > kVideoCaptureUniqueNameLength) {
|
| + WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, 0,
|
| + "Device name too long");
|
| + return nullptr;
|
| }
|
|
|
| // enumerate all video capture devices
|
| @@ -302,7 +293,7 @@ IBaseFilter * DeviceInfoDS::GetDeviceFilter(
|
| ULONG cFetched;
|
| IMoniker *pM;
|
|
|
| - IBaseFilter *captureFilter = NULL;
|
| + IBaseFilter* captureFilter = nullptr;
|
| bool deviceFound = false;
|
| while (S_OK == _dsMonikerDevEnum->Next(1, &pM, &cFetched) && !deviceFound)
|
| {
|
| @@ -328,10 +319,9 @@ IBaseFilter * DeviceInfoDS::GetDeviceFilter(
|
| {
|
| char tempDevicePathUTF8[256];
|
| tempDevicePathUTF8[0] = 0;
|
| - WideCharToMultiByte(CP_UTF8, 0, varName.bstrVal, -1,
|
| - tempDevicePathUTF8,
|
| - sizeof(tempDevicePathUTF8), NULL,
|
| - NULL);
|
| + WideCharToMultiByte(
|
| + CP_UTF8, 0, varName.bstrVal, -1, tempDevicePathUTF8,
|
| + sizeof(tempDevicePathUTF8), nullptr, nullptr);
|
| if (strncmp(tempDevicePathUTF8,
|
| (const char*) deviceUniqueIdUTF8,
|
| deviceUniqueIdUTF8Length) == 0)
|
| @@ -416,7 +406,7 @@ int32_t DeviceInfoDS::CreateCapabilityMap(
|
| RELEASE_AND_CLEAR(captureDevice);
|
| return -1;
|
| }
|
| - IAMExtDevice* extDevice = NULL;
|
| + IAMExtDevice* extDevice = nullptr;
|
| HRESULT hr = captureDevice->QueryInterface(IID_IAMExtDevice,
|
| (void **) &extDevice);
|
| if (SUCCEEDED(hr) && extDevice)
|
| @@ -426,7 +416,7 @@ int32_t DeviceInfoDS::CreateCapabilityMap(
|
| extDevice->Release();
|
| }
|
|
|
| - IAMStreamConfig* streamConfig = NULL;
|
| + IAMStreamConfig* streamConfig = nullptr;
|
| hr = outputCapturePin->QueryInterface(IID_IAMStreamConfig,
|
| (void**) &streamConfig);
|
| if (FAILED(hr))
|
| @@ -437,7 +427,7 @@ int32_t DeviceInfoDS::CreateCapabilityMap(
|
| }
|
|
|
| // this gets the FPS
|
| - IAMVideoControl* videoControlConfig = NULL;
|
| + IAMVideoControl* videoControlConfig = nullptr;
|
| HRESULT hrVC = captureDevice->QueryInterface(IID_IAMVideoControl,
|
| (void**) &videoControlConfig);
|
| if (FAILED(hrVC))
|
| @@ -446,7 +436,7 @@ int32_t DeviceInfoDS::CreateCapabilityMap(
|
| "IID_IAMVideoControl Interface NOT SUPPORTED");
|
| }
|
|
|
| - AM_MEDIA_TYPE *pmt = NULL;
|
| + AM_MEDIA_TYPE* pmt = nullptr;
|
| VIDEO_STREAM_CONFIG_CAPS caps;
|
| int count, size;
|
|
|
| @@ -673,7 +663,7 @@ int32_t DeviceInfoDS::CreateCapabilityMap(
|
| capability.rawType, capability.maxFPS);
|
| }
|
| DeleteMediaType(pmt);
|
| - pmt = NULL;
|
| + pmt = nullptr;
|
| }
|
| RELEASE_AND_CLEAR(streamConfig);
|
| RELEASE_AND_CLEAR(videoControlConfig);
|
| @@ -748,11 +738,11 @@ int32_t DeviceInfoDS::DisplayCaptureSettingsDialogBox(
|
| ReadLockScoped cs(_apiLock);
|
| HWND window = (HWND) parentWindow;
|
|
|
| - IBaseFilter* filter = GetDeviceFilter(deviceUniqueIdUTF8, NULL, 0);
|
| + IBaseFilter* filter = GetDeviceFilter(deviceUniqueIdUTF8, nullptr, 0);
|
| if (!filter)
|
| return -1;
|
|
|
| - ISpecifyPropertyPages* pPages = NULL;
|
| + ISpecifyPropertyPages* pPages = nullptr;
|
| CAUUID uuid;
|
| HRESULT hr = S_OK;
|
|
|
| @@ -779,16 +769,17 @@ int32_t DeviceInfoDS::DisplayCaptureSettingsDialogBox(
|
|
|
| // Invoke a dialog box to display.
|
|
|
| - hr = OleCreatePropertyFrame(window, // You must create the parent window.
|
| - positionX, // Horizontal position for the dialog box.
|
| - positionY, // Vertical position for the dialog box.
|
| - tempDialogTitleWide,// String used for the dialog box caption.
|
| - 1, // Number of pointers passed in pPlugin.
|
| - (LPUNKNOWN*) &filter, // Pointer to the filter.
|
| - uuid.cElems, // Number of property pages.
|
| - uuid.pElems, // Array of property page CLSIDs.
|
| - LOCALE_USER_DEFAULT, // Locale ID for the dialog box.
|
| - 0, NULL); // Reserved
|
| + hr = OleCreatePropertyFrame(
|
| + window, // You must create the parent window.
|
| + positionX, // Horizontal position for the dialog box.
|
| + positionY, // Vertical position for the dialog box.
|
| + tempDialogTitleWide, // String used for the dialog box caption.
|
| + 1, // Number of pointers passed in pPlugin.
|
| + (LPUNKNOWN*)&filter, // Pointer to the filter.
|
| + uuid.cElems, // Number of property pages.
|
| + uuid.pElems, // Array of property page CLSIDs.
|
| + LOCALE_USER_DEFAULT, // Locale ID for the dialog box.
|
| + 0, nullptr); // Reserved
|
| // Release memory.
|
| if (uuid.pElems)
|
| {
|
|
|