summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@theqtcompany.com>2015-04-09 16:09:39 +0200
committerYoann Lopes <yoann.lopes@theqtcompany.com>2015-04-14 14:49:56 +0000
commitf9145aca166ad2ca1514524ce88ded7834eb207c (patch)
tree66e6acb2ae354361250c0b3228a6c3cdb0366cfe
parent07606dde9a1f6b89f582ff8f1fbc53e2d4eb2c22 (diff)
DirectShow: correctly update camera list.
8923c0ff fixed the list not being updated after plugging/unplugging a camera from the system. However, it was only a partial fix affecting only QCameraInfo::availableCameras(). DSVideoDeviceControl was still internally keeping a list of cameras that was never updated, causing the QCamera constructor to not take into account new or removed cameras. Change-Id: Ie5e79c46002017b1e85bfc53c6391a2a747361a0 Task-number: QTBUG-39708 Reviewed-by: Christian Stromme <christian.stromme@theqtcompany.com>
-rw-r--r--src/plugins/directshow/camera/dsvideodevicecontrol.cpp72
-rw-r--r--src/plugins/directshow/camera/dsvideodevicecontrol.h10
-rw-r--r--src/plugins/directshow/dsserviceplugin.cpp52
-rw-r--r--src/plugins/directshow/dsserviceplugin.h9
4 files changed, 66 insertions, 77 deletions
diff --git a/src/plugins/directshow/camera/dsvideodevicecontrol.cpp b/src/plugins/directshow/camera/dsvideodevicecontrol.cpp
index 869299457..c3d23e027 100644
--- a/src/plugins/directshow/camera/dsvideodevicecontrol.cpp
+++ b/src/plugins/directshow/camera/dsvideodevicecontrol.cpp
@@ -33,6 +33,7 @@
#include <QDebug>
#include <QFile>
+#include <qelapsedtimer.h>
#include "dsvideodevicecontrol.h"
#include "dscamerasession.h"
@@ -48,33 +49,37 @@ extern const CLSID CLSID_VideoInputDeviceCategory;
QT_BEGIN_NAMESPACE
+Q_GLOBAL_STATIC(QList<DSVideoDeviceInfo>, deviceList)
+
DSVideoDeviceControl::DSVideoDeviceControl(QObject *parent)
: QVideoDeviceSelectorControl(parent)
{
m_session = qobject_cast<DSCameraSession*>(parent);
-
- enumerateDevices(&m_devices, &m_descriptions);
-
selected = 0;
}
int DSVideoDeviceControl::deviceCount() const
{
- return m_devices.count();
+ updateDevices();
+ return deviceList->count();
}
QString DSVideoDeviceControl::deviceName(int index) const
{
- if (index >= 0 && index <= m_devices.count())
- return QString::fromUtf8(m_devices.at(index).constData());
+ updateDevices();
+
+ if (index >= 0 && index <= deviceList->count())
+ return QString::fromUtf8(deviceList->at(index).first.constData());
return QString();
}
QString DSVideoDeviceControl::deviceDescription(int index) const
{
- if (index >= 0 && index <= m_descriptions.count())
- return m_descriptions.at(index);
+ updateDevices();
+
+ if (index >= 0 && index <= deviceList->count())
+ return deviceList->at(index).second;
return QString();
}
@@ -89,10 +94,34 @@ int DSVideoDeviceControl::selectedDevice() const
return selected;
}
-void DSVideoDeviceControl::enumerateDevices(QList<QByteArray> *devices, QStringList *descriptions)
+void DSVideoDeviceControl::setSelectedDevice(int index)
{
- devices->clear();
- descriptions->clear();
+ updateDevices();
+
+ if (index >= 0 && index < deviceList->count()) {
+ if (m_session) {
+ QString device = deviceList->at(index).first;
+ if (device.startsWith("ds:"))
+ device.remove(0,3);
+ m_session->setDevice(device);
+ }
+ selected = index;
+ }
+}
+
+const QList<DSVideoDeviceInfo> &DSVideoDeviceControl::availableDevices()
+{
+ updateDevices();
+ return *deviceList;
+}
+
+void DSVideoDeviceControl::updateDevices()
+{
+ static QElapsedTimer timer;
+ if (timer.isValid() && timer.elapsed() < 500) // ms
+ return;
+
+ deviceList->clear();
ICreateDevEnum* pDevEnum = NULL;
IEnumMoniker* pEnum = NULL;
@@ -116,7 +145,9 @@ void DSVideoDeviceControl::enumerateDevices(QList<QByteArray> *devices, QStringL
if (SUCCEEDED(hr)) {
QString output(QString::fromWCharArray(strName));
mallocInterface->Free(strName);
- devices->append(output.toUtf8().constData());
+
+ DSVideoDeviceInfo devInfo;
+ devInfo.first = output.toUtf8();
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)(&pPropBag));
@@ -130,7 +161,9 @@ void DSVideoDeviceControl::enumerateDevices(QList<QByteArray> *devices, QStringL
}
pPropBag->Release();
}
- descriptions->append(output);
+ devInfo.second = output;
+
+ deviceList->append(devInfo);
}
pMoniker->Release();
}
@@ -139,19 +172,8 @@ void DSVideoDeviceControl::enumerateDevices(QList<QByteArray> *devices, QStringL
}
pDevEnum->Release();
}
-}
-void DSVideoDeviceControl::setSelectedDevice(int index)
-{
- if (index >= 0 && index < m_devices.count()) {
- if (m_session) {
- QString device = m_devices.at(index);
- if (device.startsWith("ds:"))
- device.remove(0,3);
- m_session->setDevice(device);
- }
- selected = index;
- }
+ timer.restart();
}
QT_END_NAMESPACE
diff --git a/src/plugins/directshow/camera/dsvideodevicecontrol.h b/src/plugins/directshow/camera/dsvideodevicecontrol.h
index a6d471088..0ba7ce36a 100644
--- a/src/plugins/directshow/camera/dsvideodevicecontrol.h
+++ b/src/plugins/directshow/camera/dsvideodevicecontrol.h
@@ -42,6 +42,8 @@ class DSCameraSession;
//QTM_USE_NAMESPACE
+typedef QPair<QByteArray, QString> DSVideoDeviceInfo;
+
class DSVideoDeviceControl : public QVideoDeviceSelectorControl
{
Q_OBJECT
@@ -54,17 +56,15 @@ public:
int defaultDevice() const;
int selectedDevice() const;
- static void enumerateDevices(QList<QByteArray> *devices, QStringList *descriptions);
+ static const QList<DSVideoDeviceInfo> &availableDevices();
public Q_SLOTS:
void setSelectedDevice(int index);
private:
- DSCameraSession* m_session;
-
- QList<QByteArray> m_devices;
- QStringList m_descriptions;
+ static void updateDevices();
+ DSCameraSession* m_session;
int selected;
};
diff --git a/src/plugins/directshow/dsserviceplugin.cpp b/src/plugins/directshow/dsserviceplugin.cpp
index f28f274e2..f3713f120 100644
--- a/src/plugins/directshow/dsserviceplugin.cpp
+++ b/src/plugins/directshow/dsserviceplugin.cpp
@@ -39,7 +39,6 @@
#include "dsvideodevicecontrol.h"
#ifdef QMEDIA_DIRECTSHOW_CAMERA
-#include <QtCore/QElapsedTimer>
#include <dshow.h>
#include "dscameraservice.h"
#endif
@@ -122,9 +121,9 @@ QByteArray DSServicePlugin::defaultDevice(const QByteArray &service) const
{
#ifdef QMEDIA_DIRECTSHOW_CAMERA
if (service == Q_MEDIASERVICE_CAMERA) {
- updateDevices();
-
- return m_defaultCameraDevice;
+ const QList<DSVideoDeviceInfo> &devs = DSVideoDeviceControl::availableDevices();
+ if (!devs.isEmpty())
+ return devs.first().first;
}
#endif
@@ -133,52 +132,29 @@ QByteArray DSServicePlugin::defaultDevice(const QByteArray &service) const
QList<QByteArray> DSServicePlugin::devices(const QByteArray &service) const
{
+ QList<QByteArray> result;
+
#ifdef QMEDIA_DIRECTSHOW_CAMERA
if (service == Q_MEDIASERVICE_CAMERA) {
- updateDevices();
-
- return m_cameraDevices;
+ const QList<DSVideoDeviceInfo> &devs = DSVideoDeviceControl::availableDevices();
+ Q_FOREACH (const DSVideoDeviceInfo &info, devs)
+ result.append(info.first);
}
#endif
- return QList<QByteArray>();
+ return result;
}
QString DSServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device)
{
#ifdef QMEDIA_DIRECTSHOW_CAMERA
if (service == Q_MEDIASERVICE_CAMERA) {
- updateDevices();
-
- for (int i=0; i<m_cameraDevices.count(); i++)
- if (m_cameraDevices[i] == device)
- return m_cameraDescriptions[i];
+ const QList<DSVideoDeviceInfo> &devs = DSVideoDeviceControl::availableDevices();
+ Q_FOREACH (const DSVideoDeviceInfo &info, devs) {
+ if (info.first == device)
+ return info.second;
+ }
}
#endif
return QString();
}
-
-#ifdef QMEDIA_DIRECTSHOW_CAMERA
-
-void DSServicePlugin::updateDevices() const
-{
- static QElapsedTimer timer;
- if (timer.isValid() && timer.elapsed() < 500) // ms
- return;
-
- addRefCount();
-
- m_defaultCameraDevice.clear();
- DSVideoDeviceControl::enumerateDevices(&m_cameraDevices, &m_cameraDescriptions);
-
- if (m_cameraDevices.isEmpty()) {
- qWarning() << "No camera devices found";
- } else {
- m_defaultCameraDevice = m_cameraDevices.first();
- }
-
- releaseRefCount();
- timer.restart();
-}
-#endif
-
diff --git a/src/plugins/directshow/dsserviceplugin.h b/src/plugins/directshow/dsserviceplugin.h
index 568253497..5cc178811 100644
--- a/src/plugins/directshow/dsserviceplugin.h
+++ b/src/plugins/directshow/dsserviceplugin.h
@@ -65,15 +65,6 @@ public:
QByteArray defaultDevice(const QByteArray &service) const;
QList<QByteArray> devices(const QByteArray &service) const;
QString deviceDescription(const QByteArray &service, const QByteArray &device);
-
-private:
-#ifdef QMEDIA_DIRECTSHOW_CAMERA
- void updateDevices() const;
-
- mutable QByteArray m_defaultCameraDevice;
- mutable QList<QByteArray> m_cameraDevices;
- mutable QStringList m_cameraDescriptions;
-#endif
};
#endif // DSSERVICEPLUGIN_H