Use moniker display name for device string.

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>
This commit is contained in:
Lev Zelenskiy
2012-07-27 11:35:17 +10:00
committed by Qt by Nokia
parent a6e88ea87f
commit 42cdb92543
4 changed files with 92 additions and 148 deletions

View File

@@ -417,31 +417,23 @@ void DSCameraSession::setDevice(const QString &device)
pEnum->Reset(); pEnum->Reset();
// go through and find all video capture devices // go through and find all video capture devices
IMoniker* pMoniker = NULL; IMoniker* pMoniker = NULL;
IMalloc *mallocInterface = 0;
CoGetMalloc(1, (LPMALLOC*)&mallocInterface);
while(pEnum->Next(1, &pMoniker, NULL) == S_OK) { while(pEnum->Next(1, &pMoniker, NULL) == S_OK) {
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, BSTR strName = 0;
(void**)(&pPropBag)); hr = pMoniker->GetDisplayName(NULL, NULL, &strName);
if(FAILED(hr)) { if (SUCCEEDED(hr)) {
pMoniker->Release(); QString temp(QString::fromWCharArray(strName));
continue; // skip this one mallocInterface->Free(strName);
}
// 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));
if(temp.contains(device)) { if(temp.contains(device)) {
available = true; available = true;
} }
} }
pPropBag->Release();
pMoniker->Release(); pMoniker->Release();
} }
mallocInterface->Release();
pEnum->Release(); pEnum->Release();
} }
pDevEnum->Release(); pDevEnum->Release();
@@ -449,7 +441,7 @@ void DSCameraSession::setDevice(const QString &device)
CoUninitialize(); CoUninitialize();
if(available) { if(available) {
m_device = QByteArray(device.toLocal8Bit().constData()); m_device = QByteArray(device.toUtf8().constData());
graph = createFilterGraph(); graph = createFilterGraph();
if(!graph) if(!graph)
available = false; available = false;
@@ -698,36 +690,27 @@ bool DSCameraSession::createFilterGraph()
pDevEnum->Release(); pDevEnum->Release();
if (S_OK == hr) { if (S_OK == hr) {
pEnum->Reset(); pEnum->Reset();
IMalloc *mallocInterface = 0;
CoGetMalloc(1, (LPMALLOC*)&mallocInterface);
//go through and find all video capture devices //go through and find all video capture devices
while (pEnum->Next(1, &pMoniker, NULL) == S_OK) { while (pEnum->Next(1, &pMoniker, NULL) == S_OK) {
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0, 0, BSTR strName = 0;
IID_IPropertyBag, (void**)(&pPropBag)); hr = pMoniker->GetDisplayName(NULL, NULL, &strName);
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)) { if (SUCCEEDED(hr)) {
// check if it is the selected device QString output = QString::fromWCharArray(strName);
wcsncpy(str, varName.bstrVal, sizeof(str)/sizeof(str[0])); mallocInterface->Free(strName);
QString output = QString::fromUtf16((unsigned short*)str); if (m_device.contains(output.toUtf8().constData())) {
if (m_device.contains(output.toLocal8Bit().constData())) {
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap); hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
pPropBag->Release();
pMoniker->Release(); pMoniker->Release();
break; break;
} }
} }
} }
pPropBag->Release();
pMoniker->Release(); pMoniker->Release();
} }
mallocInterface->Release();
if (NULL == pCap) if (NULL == pCap)
{ {
if (m_device.contains("default")) if (m_device.contains("default"))
@@ -770,7 +753,7 @@ bool DSCameraSession::createFilterGraph()
return false; return false;
} }
pSG_Filter->QueryInterface(IID_ISampleGrabber, (void**)&pSG); hr = pSG_Filter->QueryInterface(IID_ISampleGrabber, (void**)&pSG);
if (FAILED(hr)) { if (FAILED(hr)) {
qWarning() << "failed to get sample grabber"; qWarning() << "failed to get sample grabber";
return false; return false;

View File

@@ -61,75 +61,28 @@ DSVideoDeviceControl::DSVideoDeviceControl(QObject *parent)
{ {
m_session = qobject_cast<DSCameraSession*>(parent); m_session = qobject_cast<DSCameraSession*>(parent);
devices.clear(); enumerateDevices(&m_devices, &m_descriptions);
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();
selected = 0; selected = 0;
} }
int DSVideoDeviceControl::deviceCount() const int DSVideoDeviceControl::deviceCount() const
{ {
return devices.count(); return m_devices.count();
} }
QString DSVideoDeviceControl::deviceName(int index) const QString DSVideoDeviceControl::deviceName(int index) const
{ {
if(index >= 0 && index <= devices.count()) if (index >= 0 && index <= m_devices.count())
return devices.at(index); return QString::fromUtf8(m_devices.at(index).constData());
return QString(); return QString();
} }
QString DSVideoDeviceControl::deviceDescription(int index) const QString DSVideoDeviceControl::deviceDescription(int index) const
{ {
if(index >= 0 && index <= descriptions.count()) if (index >= 0 && index <= m_descriptions.count())
return descriptions.at(index); return m_descriptions.at(index);
return QString(); return QString();
} }
@@ -144,11 +97,65 @@ int DSVideoDeviceControl::selectedDevice() const
return selected; 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) void DSVideoDeviceControl::setSelectedDevice(int index)
{ {
if(index >= 0 && index <= devices.count()) { if (index >= 0 && index <= m_devices.count()) {
if (m_session) { if (m_session) {
QString device = devices.at(index); QString device = m_devices.at(index);
if (device.startsWith("ds:")) if (device.startsWith("ds:"))
device.remove(0,3); device.remove(0,3);
m_session->setDevice(device); m_session->setDevice(device);

View File

@@ -43,6 +43,7 @@
#define DSVIDEODEVICECONTROL_H #define DSVIDEODEVICECONTROL_H
#include <qvideodeviceselectorcontrol.h> #include <qvideodeviceselectorcontrol.h>
#include <QStringList>
QT_BEGIN_HEADER QT_BEGIN_HEADER
@@ -63,14 +64,16 @@ public:
int defaultDevice() const; int defaultDevice() const;
int selectedDevice() const; int selectedDevice() const;
static void enumerateDevices(QList<QByteArray> *devices, QStringList *descriptions);
public Q_SLOTS: public Q_SLOTS:
void setSelectedDevice(int index); void setSelectedDevice(int index);
private: private:
DSCameraSession* m_session; DSCameraSession* m_session;
QList<QString> devices; QList<QByteArray> m_devices;
QList<QString> descriptions; QStringList m_descriptions;
int selected; int selected;
}; };

View File

@@ -44,7 +44,7 @@
#include <QtCore/QFile> #include <QtCore/QFile>
#include "dsserviceplugin.h" #include "dsserviceplugin.h"
#include "dsvideodevicecontrol.h"
#ifdef QMEDIA_DIRECTSHOW_CAMERA #ifdef QMEDIA_DIRECTSHOW_CAMERA
#include <dshow.h> #include <dshow.h>
@@ -138,58 +138,9 @@ QString DSServicePlugin::deviceDescription(const QByteArray &service, const QByt
void DSServicePlugin::updateDevices() const void DSServicePlugin::updateDevices() const
{ {
m_cameraDevices.clear(); DSVideoDeviceControl::enumerateDevices(&m_cameraDevices, &m_cameraDescriptions);
m_cameraDescriptions.clear();
BOOL bFound = TRUE; if (m_cameraDevices.isEmpty()) {
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) {
qWarning() << "No camera devices found"; qWarning() << "No camera devices found";
} }
} }