/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/video_capture/windows/device_info_ds.h"

#include <assert.h>
#include <dvdmedia.h>

#include "modules/video_capture/video_capture_config.h"
#include "modules/video_capture/windows/help_functions_ds.h"
#include "rtc_base/logging.h"
#include "rtc_base/string_utils.h"

namespace webrtc {
namespace videocapturemodule {

// static
DeviceInfoDS* DeviceInfoDS::Create() {
  DeviceInfoDS* dsInfo = new DeviceInfoDS();
  if (!dsInfo || dsInfo->Init() != 0) {
    delete dsInfo;
    dsInfo = NULL;
  }
  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".
      //
      RTC_DLOG(LS_INFO) << __FUNCTION__
                        << ": CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)"
                           " => RPC_E_CHANGED_MODE, error 0x"
                        << rtc::ToHex(hr);
    }
  }
}

DeviceInfoDS::~DeviceInfoDS() {
  RELEASE_AND_CLEAR(_dsMonikerDevEnum);
  RELEASE_AND_CLEAR(_dsDevEnum);
  if (_CoUninitializeIsRequired) {
    CoUninitialize();
  }
}

int32_t DeviceInfoDS::Init() {
  HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
                                IID_ICreateDevEnum, (void**)&_dsDevEnum);
  if (hr != NOERROR) {
    RTC_LOG(LS_INFO) << "Failed to create CLSID_SystemDeviceEnum, error 0x"
                     << rtc::ToHex(hr);
    return -1;
  }
  return 0;
}
uint32_t DeviceInfoDS::NumberOfDevices() {
  MutexLock lock(&_apiLock);
  return GetDeviceInfo(0, 0, 0, 0, 0, 0, 0);
}

int32_t DeviceInfoDS::GetDeviceName(uint32_t deviceNumber,
                                    char* deviceNameUTF8,
                                    uint32_t deviceNameLength,
                                    char* deviceUniqueIdUTF8,
                                    uint32_t deviceUniqueIdUTF8Length,
                                    char* productUniqueIdUTF8,
                                    uint32_t productUniqueIdUTF8Length) {
  MutexLock lock(&_apiLock);
  const int32_t result = GetDeviceInfo(
      deviceNumber, deviceNameUTF8, deviceNameLength, deviceUniqueIdUTF8,
      deviceUniqueIdUTF8Length, productUniqueIdUTF8, productUniqueIdUTF8Length);
  return result > (int32_t)deviceNumber ? 0 : -1;
}

int32_t DeviceInfoDS::GetDeviceInfo(uint32_t deviceNumber,
                                    char* deviceNameUTF8,
                                    uint32_t deviceNameLength,
                                    char* deviceUniqueIdUTF8,
                                    uint32_t deviceUniqueIdUTF8Length,
                                    char* productUniqueIdUTF8,
                                    uint32_t productUniqueIdUTF8Length)

{
  // enumerate all video capture devices
  RELEASE_AND_CLEAR(_dsMonikerDevEnum);
  HRESULT hr = _dsDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
                                                 &_dsMonikerDevEnum, 0);
  if (hr != NOERROR) {
    RTC_LOG(LS_INFO) << "Failed to enumerate CLSID_SystemDeviceEnum, error 0x"
                     << rtc::ToHex(hr) << ". No webcam exist?";
    return 0;
  }

  _dsMonikerDevEnum->Reset();
  ULONG cFetched;
  IMoniker* pM;
  int index = 0;
  while (S_OK == _dsMonikerDevEnum->Next(1, &pM, &cFetched)) {
    IPropertyBag* pBag;
    hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pBag);
    if (S_OK == hr) {
      // Find the description or friendly name.
      VARIANT varName;
      VariantInit(&varName);
      hr = pBag->Read(L"Description", &varName, 0);
      if (FAILED(hr)) {
        hr = pBag->Read(L"FriendlyName", &varName, 0);
      }
      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) {
                RTC_LOG(LS_INFO) << "Failed to convert device name to UTF8, "
                                    "error = "
                                 << GetLastError();
                return -1;
              }
            }
            if (deviceUniqueIdUTF8Length > 0) {
              hr = pBag->Read(L"DevicePath", &varName, 0);
              if (FAILED(hr)) {
                strncpy_s((char*)deviceUniqueIdUTF8, deviceUniqueIdUTF8Length,
                          (char*)deviceNameUTF8, convResult);
                RTC_LOG(LS_INFO) << "Failed to get "
                                    "deviceUniqueIdUTF8 using "
                                    "deviceNameUTF8";
              } else {
                convResult = WideCharToMultiByte(
                    CP_UTF8, 0, varName.bstrVal, -1, (char*)deviceUniqueIdUTF8,
                    deviceUniqueIdUTF8Length, NULL, NULL);
                if (convResult == 0) {
                  RTC_LOG(LS_INFO) << "Failed to convert device "
                                      "name to UTF8, error = "
                                   << GetLastError();
                  return -1;
                }
                if (productUniqueIdUTF8 && productUniqueIdUTF8Length > 0) {
                  GetProductId(deviceUniqueIdUTF8, productUniqueIdUTF8,
                               productUniqueIdUTF8Length);
                }
              }
            }
          }
          ++index;  // increase the number of valid devices
        }
      }
      VariantClear(&varName);
      pBag->Release();
      pM->Release();
    }
  }
  if (deviceNameLength) {
    RTC_DLOG(LS_INFO) << __FUNCTION__ << " " << deviceNameUTF8;
  }
  return index;
}

IBaseFilter* DeviceInfoDS::GetDeviceFilter(const char* deviceUniqueIdUTF8,
                                           char* productUniqueIdUTF8,
                                           uint32_t productUniqueIdUTF8Length) {
  const int32_t deviceUniqueIdUTF8Length = (int32_t)strlen(
      (char*)deviceUniqueIdUTF8);  // UTF8 is also NULL terminated
  if (deviceUniqueIdUTF8Length > kVideoCaptureUniqueNameLength) {
    RTC_LOG(LS_INFO) << "Device name too long";
    return NULL;
  }

  // enumerate all video capture devices
  RELEASE_AND_CLEAR(_dsMonikerDevEnum);
  HRESULT hr = _dsDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
                                                 &_dsMonikerDevEnum, 0);
  if (hr != NOERROR) {
    RTC_LOG(LS_INFO) << "Failed to enumerate CLSID_SystemDeviceEnum, error 0x"
                     << rtc::ToHex(hr) << ". No webcam exist?";
    return 0;
  }
  _dsMonikerDevEnum->Reset();
  ULONG cFetched;
  IMoniker* pM;

  IBaseFilter* captureFilter = NULL;
  bool deviceFound = false;
  while (S_OK == _dsMonikerDevEnum->Next(1, &pM, &cFetched) && !deviceFound) {
    IPropertyBag* pBag;
    hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pBag);
    if (S_OK == hr) {
      // Find the description or friendly name.
      VARIANT varName;
      VariantInit(&varName);
      if (deviceUniqueIdUTF8Length > 0) {
        hr = pBag->Read(L"DevicePath", &varName, 0);
        if (FAILED(hr)) {
          hr = pBag->Read(L"Description", &varName, 0);
          if (FAILED(hr)) {
            hr = pBag->Read(L"FriendlyName", &varName, 0);
          }
        }
        if (SUCCEEDED(hr)) {
          char tempDevicePathUTF8[256];
          tempDevicePathUTF8[0] = 0;
          WideCharToMultiByte(CP_UTF8, 0, varName.bstrVal, -1,
                              tempDevicePathUTF8, sizeof(tempDevicePathUTF8),
                              NULL, NULL);
          if (strncmp(tempDevicePathUTF8, (const char*)deviceUniqueIdUTF8,
                      deviceUniqueIdUTF8Length) == 0) {
            // We have found the requested device
            deviceFound = true;
            hr =
                pM->BindToObject(0, 0, IID_IBaseFilter, (void**)&captureFilter);
            if
              FAILED(hr) {
                RTC_LOG(LS_ERROR) << "Failed to bind to the selected "
                                     "capture device "
                                  << hr;
              }

            if (productUniqueIdUTF8 &&
                productUniqueIdUTF8Length > 0)  // Get the device name
            {
              GetProductId(deviceUniqueIdUTF8, productUniqueIdUTF8,
                           productUniqueIdUTF8Length);
            }
          }
        }
      }
      VariantClear(&varName);
      pBag->Release();
    }
    pM->Release();
  }
  return captureFilter;
}

int32_t DeviceInfoDS::GetWindowsCapability(
    const int32_t capabilityIndex,
    VideoCaptureCapabilityWindows& windowsCapability) {
  MutexLock lock(&_apiLock);

  if (capabilityIndex < 0 || static_cast<size_t>(capabilityIndex) >=
                                 _captureCapabilitiesWindows.size()) {
    return -1;
  }

  windowsCapability = _captureCapabilitiesWindows[capabilityIndex];
  return 0;
}

int32_t DeviceInfoDS::CreateCapabilityMap(const char* deviceUniqueIdUTF8)

{
  // Reset old capability list
  _captureCapabilities.clear();

  const int32_t deviceUniqueIdUTF8Length =
      (int32_t)strlen((char*)deviceUniqueIdUTF8);
  if (deviceUniqueIdUTF8Length > kVideoCaptureUniqueNameLength) {
    RTC_LOG(LS_INFO) << "Device name too long";
    return -1;
  }
  RTC_LOG(LS_INFO) << "CreateCapabilityMap called for device "
                   << deviceUniqueIdUTF8;

  char productId[kVideoCaptureProductIdLength];
  IBaseFilter* captureDevice = DeviceInfoDS::GetDeviceFilter(
      deviceUniqueIdUTF8, productId, kVideoCaptureProductIdLength);
  if (!captureDevice)
    return -1;
  IPin* outputCapturePin = GetOutputPin(captureDevice, GUID_NULL);
  if (!outputCapturePin) {
    RTC_LOG(LS_INFO) << "Failed to get capture device output pin";
    RELEASE_AND_CLEAR(captureDevice);
    return -1;
  }
  IAMExtDevice* extDevice = NULL;
  HRESULT hr =
      captureDevice->QueryInterface(IID_IAMExtDevice, (void**)&extDevice);
  if (SUCCEEDED(hr) && extDevice) {
    RTC_LOG(LS_INFO) << "This is an external device";
    extDevice->Release();
  }

  IAMStreamConfig* streamConfig = NULL;
  hr = outputCapturePin->QueryInterface(IID_IAMStreamConfig,
                                        (void**)&streamConfig);
  if (FAILED(hr)) {
    RTC_LOG(LS_INFO) << "Failed to get IID_IAMStreamConfig interface "
                        "from capture device";
    return -1;
  }

  // this  gets the FPS
  IAMVideoControl* videoControlConfig = NULL;
  HRESULT hrVC = captureDevice->QueryInterface(IID_IAMVideoControl,
                                               (void**)&videoControlConfig);
  if (FAILED(hrVC)) {
    RTC_LOG(LS_INFO) << "IID_IAMVideoControl Interface NOT SUPPORTED";
  }

  AM_MEDIA_TYPE* pmt = NULL;
  VIDEO_STREAM_CONFIG_CAPS caps;
  int count, size;

  hr = streamConfig->GetNumberOfCapabilities(&count, &size);
  if (FAILED(hr)) {
    RTC_LOG(LS_INFO) << "Failed to GetNumberOfCapabilities";
    RELEASE_AND_CLEAR(videoControlConfig);
    RELEASE_AND_CLEAR(streamConfig);
    RELEASE_AND_CLEAR(outputCapturePin);
    RELEASE_AND_CLEAR(captureDevice);
    return -1;
  }

  // Check if the device support formattype == FORMAT_VideoInfo2 and
  // FORMAT_VideoInfo. Prefer FORMAT_VideoInfo since some cameras (ZureCam) has
  // been seen having problem with MJPEG and FORMAT_VideoInfo2 Interlace flag is
  // only supported in FORMAT_VideoInfo2
  bool supportFORMAT_VideoInfo2 = false;
  bool supportFORMAT_VideoInfo = false;
  bool foundInterlacedFormat = false;
  GUID preferedVideoFormat = FORMAT_VideoInfo;
  for (int32_t tmp = 0; tmp < count; ++tmp) {
    hr = streamConfig->GetStreamCaps(tmp, &pmt, reinterpret_cast<BYTE*>(&caps));
    if (hr == S_OK) {
      if (pmt->majortype == MEDIATYPE_Video &&
          pmt->formattype == FORMAT_VideoInfo2) {
        RTC_LOG(LS_INFO) << "Device support FORMAT_VideoInfo2";
        supportFORMAT_VideoInfo2 = true;
        VIDEOINFOHEADER2* h =
            reinterpret_cast<VIDEOINFOHEADER2*>(pmt->pbFormat);
        assert(h);
        foundInterlacedFormat |=
            h->dwInterlaceFlags &
            (AMINTERLACE_IsInterlaced | AMINTERLACE_DisplayModeBobOnly);
      }
      if (pmt->majortype == MEDIATYPE_Video &&
          pmt->formattype == FORMAT_VideoInfo) {
        RTC_LOG(LS_INFO) << "Device support FORMAT_VideoInfo2";
        supportFORMAT_VideoInfo = true;
      }
    }
  }
  if (supportFORMAT_VideoInfo2) {
    if (supportFORMAT_VideoInfo && !foundInterlacedFormat) {
      preferedVideoFormat = FORMAT_VideoInfo;
    } else {
      preferedVideoFormat = FORMAT_VideoInfo2;
    }
  }

  for (int32_t tmp = 0; tmp < count; ++tmp) {
    hr = streamConfig->GetStreamCaps(tmp, &pmt, reinterpret_cast<BYTE*>(&caps));
    if (hr != S_OK) {
      RTC_LOG(LS_INFO) << "Failed to GetStreamCaps";
      RELEASE_AND_CLEAR(videoControlConfig);
      RELEASE_AND_CLEAR(streamConfig);
      RELEASE_AND_CLEAR(outputCapturePin);
      RELEASE_AND_CLEAR(captureDevice);
      return -1;
    }

    if (pmt->majortype == MEDIATYPE_Video &&
        pmt->formattype == preferedVideoFormat) {
      VideoCaptureCapabilityWindows capability;
      int64_t avgTimePerFrame = 0;

      if (pmt->formattype == FORMAT_VideoInfo) {
        VIDEOINFOHEADER* h = reinterpret_cast<VIDEOINFOHEADER*>(pmt->pbFormat);
        assert(h);
        capability.directShowCapabilityIndex = tmp;
        capability.width = h->bmiHeader.biWidth;
        capability.height = h->bmiHeader.biHeight;
        avgTimePerFrame = h->AvgTimePerFrame;
      }
      if (pmt->formattype == FORMAT_VideoInfo2) {
        VIDEOINFOHEADER2* h =
            reinterpret_cast<VIDEOINFOHEADER2*>(pmt->pbFormat);
        assert(h);
        capability.directShowCapabilityIndex = tmp;
        capability.width = h->bmiHeader.biWidth;
        capability.height = h->bmiHeader.biHeight;
        capability.interlaced =
            h->dwInterlaceFlags &
            (AMINTERLACE_IsInterlaced | AMINTERLACE_DisplayModeBobOnly);
        avgTimePerFrame = h->AvgTimePerFrame;
      }

      if (hrVC == S_OK) {
        LONGLONG* frameDurationList;
        LONGLONG maxFPS;
        long listSize;
        SIZE size;
        size.cx = capability.width;
        size.cy = capability.height;

        // GetMaxAvailableFrameRate doesn't return max frame rate always
        // eg: Logitech Notebook. This may be due to a bug in that API
        // because GetFrameRateList array is reversed in the above camera. So
        // a util method written. Can't assume the first value will return
        // the max fps.
        hrVC = videoControlConfig->GetFrameRateList(
            outputCapturePin, tmp, size, &listSize, &frameDurationList);

        // On some odd cameras, you may get a 0 for duration.
        // GetMaxOfFrameArray returns the lowest duration (highest FPS)
        if (hrVC == S_OK && listSize > 0 &&
            0 != (maxFPS = GetMaxOfFrameArray(frameDurationList, listSize))) {
          capability.maxFPS = static_cast<int>(10000000 / maxFPS);
          capability.supportFrameRateControl = true;
        } else  // use existing method
        {
          RTC_LOG(LS_INFO) << "GetMaxAvailableFrameRate NOT SUPPORTED";
          if (avgTimePerFrame > 0)
            capability.maxFPS = static_cast<int>(10000000 / avgTimePerFrame);
          else
            capability.maxFPS = 0;
        }
      } else  // use existing method in case IAMVideoControl is not supported
      {
        if (avgTimePerFrame > 0)
          capability.maxFPS = static_cast<int>(10000000 / avgTimePerFrame);
        else
          capability.maxFPS = 0;
      }

      // can't switch MEDIATYPE :~(
      if (pmt->subtype == MEDIASUBTYPE_I420) {
        capability.videoType = VideoType::kI420;
      } else if (pmt->subtype == MEDIASUBTYPE_IYUV) {
        capability.videoType = VideoType::kIYUV;
      } else if (pmt->subtype == MEDIASUBTYPE_RGB24) {
        capability.videoType = VideoType::kRGB24;
      } else if (pmt->subtype == MEDIASUBTYPE_YUY2) {
        capability.videoType = VideoType::kYUY2;
      } else if (pmt->subtype == MEDIASUBTYPE_RGB565) {
        capability.videoType = VideoType::kRGB565;
      } else if (pmt->subtype == MEDIASUBTYPE_MJPG) {
        capability.videoType = VideoType::kMJPEG;
      } else if (pmt->subtype == MEDIASUBTYPE_dvsl ||
                 pmt->subtype == MEDIASUBTYPE_dvsd ||
                 pmt->subtype ==
                     MEDIASUBTYPE_dvhd)  // If this is an external DV camera
      {
        capability.videoType =
            VideoType::kYUY2;  // MS DV filter seems to create this type
      } else if (pmt->subtype ==
                 MEDIASUBTYPE_UYVY)  // Seen used by Declink capture cards
      {
        capability.videoType = VideoType::kUYVY;
      } 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
      {
        RTC_LOG(LS_INFO) << "Device support HDYC.";
        capability.videoType = VideoType::kUYVY;
      } else {
        WCHAR strGuid[39];
        StringFromGUID2(pmt->subtype, strGuid, 39);
        RTC_LOG(LS_WARNING)
            << "Device support unknown media type " << strGuid << ", width "
            << capability.width << ", height " << capability.height;
        continue;
      }

      _captureCapabilities.push_back(capability);
      _captureCapabilitiesWindows.push_back(capability);
      RTC_LOG(LS_INFO) << "Camera capability, width:" << capability.width
                       << " height:" << capability.height
                       << " type:" << static_cast<int>(capability.videoType)
                       << " fps:" << capability.maxFPS;
    }
    FreeMediaType(pmt);
    pmt = NULL;
  }
  RELEASE_AND_CLEAR(streamConfig);
  RELEASE_AND_CLEAR(videoControlConfig);
  RELEASE_AND_CLEAR(outputCapturePin);
  RELEASE_AND_CLEAR(captureDevice);  // Release the capture device

  // Store the new used device name
  _lastUsedDeviceNameLength = deviceUniqueIdUTF8Length;
  _lastUsedDeviceName =
      (char*)realloc(_lastUsedDeviceName, _lastUsedDeviceNameLength + 1);
  memcpy(_lastUsedDeviceName, deviceUniqueIdUTF8,
         _lastUsedDeviceNameLength + 1);
  RTC_LOG(LS_INFO) << "CreateCapabilityMap " << _captureCapabilities.size();

  return static_cast<int32_t>(_captureCapabilities.size());
}

// Constructs a product ID from the Windows DevicePath. on a USB device the
// devicePath contains product id and vendor id. This seems to work for firewire
// as well.
// Example of device path:
// "\\?\usb#vid_0408&pid_2010&mi_00#7&258e7aaf&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
// "\\?\avc#sony&dv-vcr&camcorder&dv#65b2d50301460008#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
void DeviceInfoDS::GetProductId(const char* devicePath,
                                char* productUniqueIdUTF8,
                                uint32_t productUniqueIdUTF8Length) {
  *productUniqueIdUTF8 = '\0';
  char* startPos = strstr((char*)devicePath, "\\\\?\\");
  if (!startPos) {
    strncpy_s((char*)productUniqueIdUTF8, productUniqueIdUTF8Length, "", 1);
    RTC_LOG(LS_INFO) << "Failed to get the product Id";
    return;
  }
  startPos += 4;

  char* pos = strchr(startPos, '&');
  if (!pos || pos >= (char*)devicePath + strlen((char*)devicePath)) {
    strncpy_s((char*)productUniqueIdUTF8, productUniqueIdUTF8Length, "", 1);
    RTC_LOG(LS_INFO) << "Failed to get the product Id";
    return;
  }
  // Find the second occurrence.
  pos = strchr(pos + 1, '&');
  uint32_t bytesToCopy = (uint32_t)(pos - startPos);
  if (pos && (bytesToCopy <= productUniqueIdUTF8Length) &&
      bytesToCopy <= kVideoCaptureProductIdLength) {
    strncpy_s((char*)productUniqueIdUTF8, productUniqueIdUTF8Length,
              (char*)startPos, bytesToCopy);
  } else {
    strncpy_s((char*)productUniqueIdUTF8, productUniqueIdUTF8Length, "", 1);
    RTC_LOG(LS_INFO) << "Failed to get the product Id";
  }
}

int32_t DeviceInfoDS::DisplayCaptureSettingsDialogBox(
    const char* deviceUniqueIdUTF8,
    const char* dialogTitleUTF8,
    void* parentWindow,
    uint32_t positionX,
    uint32_t positionY) {
  MutexLock lock(&_apiLock);
  HWND window = (HWND)parentWindow;

  IBaseFilter* filter = GetDeviceFilter(deviceUniqueIdUTF8, NULL, 0);
  if (!filter)
    return -1;

  ISpecifyPropertyPages* pPages = NULL;
  CAUUID uuid;
  HRESULT hr = S_OK;

  hr = filter->QueryInterface(IID_ISpecifyPropertyPages, (LPVOID*)&pPages);
  if (!SUCCEEDED(hr)) {
    filter->Release();
    return -1;
  }
  hr = pPages->GetPages(&uuid);
  if (!SUCCEEDED(hr)) {
    filter->Release();
    return -1;
  }

  WCHAR tempDialogTitleWide[256];
  tempDialogTitleWide[0] = 0;
  int size = 255;

  // UTF-8 to wide char
  MultiByteToWideChar(CP_UTF8, 0, (char*)dialogTitleUTF8, -1,
                      tempDialogTitleWide, size);

  // 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
  // Release memory.
  if (uuid.pElems) {
    CoTaskMemFree(uuid.pElems);
  }
  filter->Release();
  return 0;
}
}  // namespace videocapturemodule
}  // namespace webrtc
