/*
 *  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 "webrtc/modules/video_capture/windows/device_info_ds.h"

#include <ios>  // std::hex

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

#include <Dvdmedia.h>
#include <Streams.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".
            //
            LOG(LS_INFO) << __FUNCTION__
                         << ": CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)"
                         << " => RPC_E_CHANGED_MODE, error 0x" << std::hex
                         << 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)
    {
        LOG(LS_INFO) << "Failed to create CLSID_SystemDeviceEnum, error 0x"
                     << std::hex << hr;
        return -1;
    }
    return 0;
}
uint32_t DeviceInfoDS::NumberOfDevices()
{
    ReadLockScoped cs(_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)
{
    ReadLockScoped cs(_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)
    {
        LOG(LS_INFO) << "Failed to enumerate CLSID_SystemDeviceEnum, error 0x"
                     << std::hex << 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)
                            {
                                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);
                                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)
                                {
                                    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)
    {
        LOG(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)
    {
        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)
    {
        LOG(LS_INFO) << "Failed to enumerate CLSID_SystemDeviceEnum, error 0x"
                     << std::hex << 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)
                        {
                            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) {
  ReadLockScoped cs(_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)
    {
        LOG(LS_INFO) << "Device name too long";
        return -1;
    }
    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)
    {
        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)
    {
        LOG(LS_INFO) << "This is an external device";
        extDevice->Release();
    }

    IAMStreamConfig* streamConfig = NULL;
    hr = outputCapturePin->QueryInterface(IID_IAMStreamConfig,
                                          (void**) &streamConfig);
    if (FAILED(hr))
    {
        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))
    {
        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))
    {
        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 (!FAILED(hr))
        {
            if (pmt->majortype == MEDIATYPE_Video
                && pmt->formattype == FORMAT_VideoInfo2)
            {
                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)
            {
                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 (FAILED(hr))
        {
            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
                {
                    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
            {
                LOG(LS_INFO) << "Device support HDYC.";
                capability.videoType = VideoType::kUYVY;
            }
            else
            {
                WCHAR strGuid[39];
                StringFromGUID2(pmt->subtype, strGuid, 39);
                LOG(LS_WARNING) << "Device support unknown media type "
                                << strGuid << ", width " << capability.width
                                << ", height " << capability.height;
                continue;
            }

            _captureCapabilities.push_back(capability);
            _captureCapabilitiesWindows.push_back(capability);
            LOG(LS_INFO) << "Camera capability, width:" << capability.width
                         << " height:" << capability.height << " type:"
                         << static_cast<int>(capability.videoType) << " fps:"
                         << capability.maxFPS;
        }
        DeleteMediaType(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);
    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);
        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);
        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);
        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)
{
    ReadLockScoped cs(_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
