Use moniker display name for device string.
authorLev Zelenskiy <lev.zelenskiy@nokia.com>
Fri, 27 Jul 2012 01:35:17 +0000 (11:35 +1000)
committerQt by Nokia <qt-info@nokia.com>
Fri, 3 Aug 2012 04:01:13 +0000 (06:01 +0200)
Moniker names are unique, while device friendly names are not.

Change-Id: Ic3e842e49d04c502cf5ad1fc40f89db657f0401a
Reviewed-by: Michael Goddard <michael.goddard@nokia.com>
Reviewed-by: Ling Hu <ling.hu@nokia.com>
src/plugins/directshow/camera/dscamerasession.cpp
src/plugins/directshow/camera/dsvideodevicecontrol.cpp
src/plugins/directshow/camera/dsvideodevicecontrol.h
src/plugins/directshow/dsserviceplugin.cpp

index ccc39a8..71151b5 100644 (file)
@@ -417,31 +417,23 @@ void DSCameraSession::setDevice(const QString &device)
             pEnum->Reset();
             // go through and find all video capture devices
             IMoniker* pMoniker = NULL;
+            IMalloc *mallocInterface = 0;
+            CoGetMalloc(1, (LPMALLOC*)&mallocInterface);
             while(pEnum->Next(1, &pMoniker, NULL) == S_OK) {
-                IPropertyBag *pPropBag;
-                hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
-                                             (void**)(&pPropBag));
-                if(FAILED(hr)) {
-                    pMoniker->Release();
-                    continue; // skip this one
-                }
-                // Find the description
-                WCHAR str[120];
-                VARIANT varName;
-                varName.vt = VT_BSTR;
-                hr = pPropBag->Read(L"Description", &varName, 0);
-                if(FAILED(hr))
-                    hr = pPropBag->Read(L"FriendlyName", &varName, 0);
-                if(SUCCEEDED(hr)) {
-                    wcsncpy(str, varName.bstrVal, sizeof(str)/sizeof(str[0]));
-                    QString temp(QString::fromUtf16((unsigned short*)str));
+
+                BSTR strName = 0;
+                hr = pMoniker->GetDisplayName(NULL, NULL, &strName);
+                if (SUCCEEDED(hr)) {
+                    QString temp(QString::fromWCharArray(strName));
+                    mallocInterface->Free(strName);
                     if(temp.contains(device)) {
                         available = true;
                     }
                 }
-                pPropBag->Release();
+
                 pMoniker->Release();
             }
+            mallocInterface->Release();
             pEnum->Release();
         }
         pDevEnum->Release();
@@ -449,7 +441,7 @@ void DSCameraSession::setDevice(const QString &device)
     CoUninitialize();
 
     if(available) {
-        m_device = QByteArray(device.toLocal8Bit().constData());
+        m_device = QByteArray(device.toUtf8().constData());
         graph = createFilterGraph();
         if(!graph)
             available = false;
@@ -698,36 +690,27 @@ bool DSCameraSession::createFilterGraph()
         pDevEnum->Release();
         if (S_OK == hr) {
             pEnum->Reset();
+            IMalloc *mallocInterface = 0;
+            CoGetMalloc(1, (LPMALLOC*)&mallocInterface);
             //go through and find all video capture devices
             while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
-                IPropertyBag *pPropBag;
-                hr = pMoniker->BindToStorage(0, 0,
-                                             IID_IPropertyBag, (void**)(&pPropBag));
-                if(FAILED(hr)) {
-                    pMoniker->Release();
-                    continue; // skip this one
-                }
-                // Find the description
-                WCHAR str[120];
-                VARIANT varName;
-                varName.vt = VT_BSTR;
-                hr = pPropBag->Read(L"FriendlyName", &varName, 0);
+
+                BSTR strName = 0;
+                hr = pMoniker->GetDisplayName(NULL, NULL, &strName);
                 if (SUCCEEDED(hr)) {
-                    // check if it is the selected device
-                    wcsncpy(str, varName.bstrVal, sizeof(str)/sizeof(str[0]));
-                    QString output = QString::fromUtf16((unsigned short*)str);
-                    if (m_device.contains(output.toLocal8Bit().constData())) {
+                    QString output = QString::fromWCharArray(strName);
+                    mallocInterface->Free(strName);
+                    if (m_device.contains(output.toUtf8().constData())) {
                         hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);
                         if (SUCCEEDED(hr)) {
-                            pPropBag->Release();
                             pMoniker->Release();
                             break;
                         }
                     }
                 }
-                pPropBag->Release();
                 pMoniker->Release();
             }
+            mallocInterface->Release();
             if (NULL == pCap)
             {
                 if (m_device.contains("default"))
@@ -770,7 +753,7 @@ bool DSCameraSession::createFilterGraph()
         return false;
     }
 
-    pSG_Filter->QueryInterface(IID_ISampleGrabber, (void**)&pSG);
+    hr = pSG_Filter->QueryInterface(IID_ISampleGrabber, (void**)&pSG);
     if (FAILED(hr)) {
         qWarning() << "failed to get sample grabber";
         return false;
index 94b0704..7084c8e 100644 (file)
@@ -61,75 +61,28 @@ DSVideoDeviceControl::DSVideoDeviceControl(QObject *parent)
 {
     m_session = qobject_cast<DSCameraSession*>(parent);
 
-    devices.clear();
-    descriptions.clear();
-
-    CoInitialize(NULL);
-    ICreateDevEnum* pDevEnum = NULL;
-    IEnumMoniker* pEnum = NULL;
-    // Create the System device enumerator
-    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
-            CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
-            reinterpret_cast<void**>(&pDevEnum));
-    if(SUCCEEDED(hr)) {
-        // Create the enumerator for the video capture category
-        hr = pDevEnum->CreateClassEnumerator(
-                CLSID_VideoInputDeviceCategory, &pEnum, 0);
-        if (S_OK == hr) {
-            pEnum->Reset();
-            // go through and find all video capture devices
-            IMoniker* pMoniker = NULL;
-            while(pEnum->Next(1, &pMoniker, NULL) == S_OK) {
-                IPropertyBag *pPropBag;
-                hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
-                        (void**)(&pPropBag));
-                if(FAILED(hr)) {
-                    pMoniker->Release();
-                    continue; // skip this one
-                }
-                // Find the description
-                WCHAR str[120];
-                VARIANT varName;
-                varName.vt = VT_BSTR;
-                hr = pPropBag->Read(L"FriendlyName", &varName, 0);
-                if(SUCCEEDED(hr)) {
-                    wcsncpy(str, varName.bstrVal, sizeof(str)/sizeof(str[0]));
-                    QString temp(QString::fromUtf16((unsigned short*)str));
-                    devices.append(QString("ds:%1").arg(temp).toLocal8Bit().constData());
-                    hr = pPropBag->Read(L"Description", &varName, 0);
-                    wcsncpy(str, varName.bstrVal, sizeof(str)/sizeof(str[0]));
-                    QString temp2(QString::fromUtf16((unsigned short*)str));
-                    descriptions.append(temp2.toLocal8Bit().constData());
-                }
-                pPropBag->Release();
-                pMoniker->Release();
-            }
-            pEnum->Release();
-        }
-        pDevEnum->Release();
-    }
-    CoUninitialize();
+    enumerateDevices(&m_devices, &m_descriptions);
 
     selected = 0;
 }
 
 int DSVideoDeviceControl::deviceCount() const
 {
-    return devices.count();
+    return m_devices.count();
 }
 
 QString DSVideoDeviceControl::deviceName(int index) const
 {
-    if(index >= 0 && index <= devices.count())
-        return devices.at(index);
+    if (index >= 0 && index <= m_devices.count())
+        return QString::fromUtf8(m_devices.at(index).constData());
 
     return QString();
 }
 
 QString DSVideoDeviceControl::deviceDescription(int index) const
 {
-    if(index >= 0 && index <= descriptions.count())
-        return descriptions.at(index);
+    if (index >= 0 && index <= m_descriptions.count())
+        return m_descriptions.at(index);
 
     return QString();
 }
@@ -144,11 +97,65 @@ int DSVideoDeviceControl::selectedDevice() const
     return selected;
 }
 
+void DSVideoDeviceControl::enumerateDevices(QList<QByteArray> *devices, QStringList *descriptions)
+{
+    devices->clear();
+    descriptions->clear();
+
+    CoInitialize(NULL);
+    ICreateDevEnum* pDevEnum = NULL;
+    IEnumMoniker* pEnum = NULL;
+    // Create the System device enumerator
+    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
+            CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
+            reinterpret_cast<void**>(&pDevEnum));
+    if (SUCCEEDED(hr)) {
+        // Create the enumerator for the video capture category
+        hr = pDevEnum->CreateClassEnumerator(
+                CLSID_VideoInputDeviceCategory, &pEnum, 0);
+        if (S_OK == hr) {
+            pEnum->Reset();
+            // go through and find all video capture devices
+            IMoniker* pMoniker = NULL;
+            IMalloc *mallocInterface = 0;
+            CoGetMalloc(1, (LPMALLOC*)&mallocInterface);
+            while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
+                BSTR strName = 0;
+                hr = pMoniker->GetDisplayName(NULL, NULL, &strName);
+                if (SUCCEEDED(hr)) {
+                    QString output(QString::fromWCharArray(strName));
+                    mallocInterface->Free(strName);
+                    devices->append(output.toUtf8().constData());
+
+                    IPropertyBag *pPropBag;
+                    hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
+                    if (SUCCEEDED(hr)) {
+                        // Find the description
+                        VARIANT varName;
+                        varName.vt = VT_BSTR;
+                        hr = pPropBag->Read(L"FriendlyName", &varName, 0);
+                        if (SUCCEEDED(hr)) {
+                            output = QString::fromWCharArray(varName.bstrVal);
+                        }
+                        pPropBag->Release();
+                    }
+                    descriptions->append(output);
+                }
+                pMoniker->Release();
+            }
+            mallocInterface->Release();
+            pEnum->Release();
+        }
+        pDevEnum->Release();
+    }
+    CoUninitialize();
+}
+
 void DSVideoDeviceControl::setSelectedDevice(int index)
 {
-    if(index >= 0 && index <= devices.count()) {
+    if (index >= 0 && index <= m_devices.count()) {
         if (m_session) {
-            QString device = devices.at(index);
+            QString device = m_devices.at(index);
             if (device.startsWith("ds:"))
                 device.remove(0,3);
             m_session->setDevice(device);
index 7dbf248..0a621d0 100644 (file)
@@ -43,6 +43,7 @@
 #define DSVIDEODEVICECONTROL_H
 
 #include <qvideodeviceselectorcontrol.h>
+#include <QStringList>
 
 QT_BEGIN_HEADER
 
@@ -63,14 +64,16 @@ public:
     int defaultDevice() const;
     int selectedDevice() const;
 
+    static void enumerateDevices(QList<QByteArray> *devices, QStringList *descriptions);
+
 public Q_SLOTS:
     void setSelectedDevice(int index);
 
 private:
     DSCameraSession* m_session;
 
-    QList<QString> devices;
-    QList<QString> descriptions;
+    QList<QByteArray> m_devices;
+    QStringList m_descriptions;
 
     int selected;
 };
index d3871c8..84ba84f 100644 (file)
@@ -44,7 +44,7 @@
 #include <QtCore/QFile>
 
 #include "dsserviceplugin.h"
-
+#include "dsvideodevicecontrol.h"
 
 #ifdef QMEDIA_DIRECTSHOW_CAMERA
 #include <dshow.h>
@@ -138,58 +138,9 @@ QString DSServicePlugin::deviceDescription(const QByteArray &service, const QByt
 
 void DSServicePlugin::updateDevices() const
 {
-    m_cameraDevices.clear();
-    m_cameraDescriptions.clear();
-    BOOL bFound = TRUE;
-    CoInitialize(NULL);
-    ICreateDevEnum* pDevEnum = NULL;
-    IEnumMoniker* pEnum = NULL;
-    // Create the System device enumerator
-    HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
-                 CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
-                reinterpret_cast<void**>(&pDevEnum));
-    if(SUCCEEDED(hr)) {
-        // Create the enumerator for the video capture category
-       hr = pDevEnum->CreateClassEnumerator(
-            CLSID_VideoInputDeviceCategory, &pEnum, 0);
-        if (S_OK == hr) {
-            pEnum->Reset();
-            // go through and find all video capture devices
-            IMoniker* pMoniker = NULL;
-            while(pEnum->Next(1, &pMoniker, NULL) == S_OK) {
-                IPropertyBag *pPropBag;
-                hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,
-                     (void**)(&pPropBag));
-                if(FAILED(hr)) {
-                    pMoniker->Release();
-                    continue; // skip this one
-                }
-                bFound = TRUE;
-                // Find the description
-                WCHAR str[120];
-                VARIANT varName;
-                varName.vt = VT_BSTR;
-                hr = pPropBag->Read(L"FriendlyName", &varName, 0);
-                if(SUCCEEDED(hr)) {
-                    wcsncpy(str, varName.bstrVal, sizeof(str)/sizeof(str[0]));
-                    QString temp(QString::fromUtf16((unsigned short*)str));
-                    m_cameraDevices.append(QString("ds:%1").arg(temp).toLocal8Bit().constData());
-                    hr = pPropBag->Read(L"Description", &varName, 0);
-                    wcsncpy(str, varName.bstrVal, sizeof(str)/sizeof(str[0]));
-                    QString temp2(QString::fromUtf16((unsigned short*)str));
-                    m_cameraDescriptions.append(temp2);
-                } else {
-                    qWarning() << "No friendly name";
-                }
-                pPropBag->Release();
-                pMoniker->Release();
-            }
-            pEnum->Release();
-        }
-        pDevEnum->Release();
-    }
-    CoUninitialize();
-    if (!bFound) {
+    DSVideoDeviceControl::enumerateDevices(&m_cameraDevices, &m_cameraDescriptions);
+
+    if (m_cameraDevices.isEmpty()) {
         qWarning() << "No camera devices found";
     }
 }