| 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) | 
| { | 
|  |