New QCameraInfo class.

The class allows to get the list of available cameras on the system as
well as getting some static information about them such as their unique
ID, display name, physical position and sensor orientation.

This makes QCamera::availableDevices() and QCamera::deviceDescription()
obsolete.

This patch contains the API, documentation and auto-tests but not the
actual implementation by each backend (except for retrieving the default
camera device).

[ChangeLog][QtMultimedia] Added new QCameraInfo class
[ChangeLog][QtMultimedia] QCamera: availableDevices() and
deviceDescription() are deprecated, use QCameraInfo instead

Change-Id: I64fd65729ab26a789468979ed5444ee90bb82cd0
Reviewed-by: Christian Stromme <christian.stromme@digia.com>
This commit is contained in:
Yoann Lopes
2014-01-22 16:18:42 +01:00
committed by The Qt Project
parent d964388b38
commit b28ee24628
54 changed files with 2218 additions and 154 deletions

View File

@@ -46,6 +46,7 @@
QT_BEGIN_NAMESPACE
QByteArray QAndroidVideoDeviceSelectorControl::m_defaultDevice;
QList<QByteArray> QAndroidVideoDeviceSelectorControl::m_names;
QStringList QAndroidVideoDeviceSelectorControl::m_descriptions;
@@ -99,6 +100,7 @@ void QAndroidVideoDeviceSelectorControl::setSelectedDevice(int index)
void QAndroidVideoDeviceSelectorControl::update()
{
m_defaultDevice.clear();
m_names.clear();
m_descriptions.clear();
@@ -127,6 +129,17 @@ void QAndroidVideoDeviceSelectorControl::update()
break;
}
}
if (!m_names.isEmpty())
m_defaultDevice = m_names.first();
}
QByteArray QAndroidVideoDeviceSelectorControl::defaultDeviceName()
{
if (m_names.isEmpty())
update();
return m_defaultDevice;
}
QList<QByteArray> QAndroidVideoDeviceSelectorControl::availableDevices()

View File

@@ -66,6 +66,7 @@ public:
void setSelectedDevice(int index);
static QByteArray defaultDeviceName();
static QList<QByteArray> availableDevices();
static QString availableDeviceDescription(const QByteArray &device);
@@ -73,6 +74,7 @@ private:
static void update();
int m_selectedDevice;
static QByteArray m_defaultDevice;
static QList<QByteArray> m_names;
static QStringList m_descriptions;

View File

@@ -96,6 +96,14 @@ QMediaServiceProviderHint::Features QAndroidMediaServicePlugin::supportedFeature
return QMediaServiceProviderHint::Features();
}
QByteArray QAndroidMediaServicePlugin::defaultDevice(const QByteArray &service) const
{
if (service == Q_MEDIASERVICE_CAMERA)
return QAndroidVideoDeviceSelectorControl::defaultDeviceName();
return QByteArray();
}
QList<QByteArray> QAndroidMediaServicePlugin::devices(const QByteArray &service) const
{
if (service == Q_MEDIASERVICE_CAMERA)

View File

@@ -49,10 +49,12 @@ QT_BEGIN_NAMESPACE
class QAndroidMediaServicePlugin
: public QMediaServiceProviderPlugin
, public QMediaServiceSupportedDevicesInterface
, public QMediaServiceDefaultDeviceInterface
, public QMediaServiceFeaturesInterface
{
Q_OBJECT
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
Q_INTERFACES(QMediaServiceFeaturesInterface)
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0"
FILE "android_mediaservice.json")
@@ -66,6 +68,7 @@ public:
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const Q_DECL_OVERRIDE;
QByteArray defaultDevice(const QByteArray &service) const;
QList<QByteArray> devices(const QByteArray &service) const;
QString deviceDescription(const QByteArray &service, const QByteArray &device);
};

View File

@@ -49,10 +49,12 @@
QT_BEGIN_NAMESPACE
class AVFServicePlugin : public QMediaServiceProviderPlugin,
public QMediaServiceSupportedDevicesInterface
public QMediaServiceSupportedDevicesInterface,
public QMediaServiceDefaultDeviceInterface
{
Q_OBJECT
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "avfcamera.json")
public:
@@ -61,12 +63,14 @@ public:
QMediaService* create(QString const& key);
void release(QMediaService *service);
QByteArray defaultDevice(const QByteArray &service) const;
QList<QByteArray> devices(const QByteArray &service) const;
QString deviceDescription(const QByteArray &service, const QByteArray &device);
private:
void updateDevices() const;
mutable QByteArray m_defaultCameraDevice;
mutable QList<QByteArray> m_cameraDevices;
mutable QMap<QByteArray, QString> m_cameraDescriptions;
};

View File

@@ -72,6 +72,18 @@ void AVFServicePlugin::release(QMediaService *service)
delete service;
}
QByteArray AVFServicePlugin::defaultDevice(const QByteArray &service) const
{
if (service == Q_MEDIASERVICE_CAMERA) {
if (m_cameraDevices.isEmpty())
updateDevices();
return m_defaultCameraDevice;
}
return QByteArray();
}
QList<QByteArray> AVFServicePlugin::devices(const QByteArray &service) const
{
if (service == Q_MEDIASERVICE_CAMERA) {
@@ -98,9 +110,14 @@ QString AVFServicePlugin::deviceDescription(const QByteArray &service, const QBy
void AVFServicePlugin::updateDevices() const
{
m_defaultCameraDevice.clear();
m_cameraDevices.clear();
m_cameraDescriptions.clear();
AVCaptureDevice *defaultDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if (defaultDevice)
m_defaultCameraDevice = QByteArray([[defaultDevice uniqueID] UTF8String]);
NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *device in videoDevices) {
QByteArray deviceId([[device uniqueID] UTF8String]);

View File

@@ -80,6 +80,7 @@ private:
int m_selectedDevice;
bool m_dirty;
int m_defaultDevice;
QStringList m_devices;
QStringList m_deviceDescriptions;
};

View File

@@ -50,11 +50,17 @@ AVFVideoDeviceControl::AVFVideoDeviceControl(AVFCameraService *service, QObject
, m_service(service)
, m_selectedDevice(0)
, m_dirty(true)
, m_defaultDevice(0)
{
AVCaptureDevice *defaultDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
int i = 0;
for (AVCaptureDevice *device in videoDevices) {
m_devices << QString::fromUtf8([[device uniqueID] UTF8String]);
m_deviceDescriptions << QString::fromUtf8([[device localizedName] UTF8String]);
if (defaultDevice && [[device uniqueID] isEqualToString:[defaultDevice uniqueID]])
m_defaultDevice = i;
++i;
}
}
@@ -79,7 +85,7 @@ QString AVFVideoDeviceControl::deviceDescription(int index) const
int AVFVideoDeviceControl::defaultDevice() const
{
return 0;
return m_defaultDevice;
}
int AVFVideoDeviceControl::selectedDevice() const

View File

@@ -153,7 +153,7 @@ void DSVideoDeviceControl::enumerateDevices(QList<QByteArray> *devices, QStringL
void DSVideoDeviceControl::setSelectedDevice(int index)
{
if (index >= 0 && index <= m_devices.count()) {
if (index >= 0 && index < m_devices.count()) {
if (m_session) {
QString device = m_devices.at(index);
if (device.startsWith("ds:"))

View File

@@ -107,6 +107,20 @@ QMediaServiceProviderHint::Features DSServicePlugin::supportedFeatures(
return QMediaServiceProviderHint::Features();
}
QByteArray DSServicePlugin::defaultDevice(const QByteArray &service) const
{
#ifdef QMEDIA_DIRECTSHOW_CAMERA
if (service == Q_MEDIASERVICE_CAMERA) {
if (m_cameraDevices.isEmpty())
updateDevices();
return m_defaultCameraDevice;
}
#endif
return QByteArray();
}
QList<QByteArray> DSServicePlugin::devices(const QByteArray &service) const
{
#ifdef QMEDIA_DIRECTSHOW_CAMERA
@@ -140,10 +154,13 @@ QString DSServicePlugin::deviceDescription(const QByteArray &service, const QByt
void DSServicePlugin::updateDevices() const
{
m_defaultCameraDevice.clear();
DSVideoDeviceControl::enumerateDevices(&m_cameraDevices, &m_cameraDescriptions);
if (m_cameraDevices.isEmpty()) {
qWarning() << "No camera devices found";
} else {
m_defaultCameraDevice = m_cameraDevices.first();
}
}
#endif

View File

@@ -49,10 +49,12 @@ QT_USE_NAMESPACE
class DSServicePlugin
: public QMediaServiceProviderPlugin
, public QMediaServiceSupportedDevicesInterface
, public QMediaServiceDefaultDeviceInterface
, public QMediaServiceFeaturesInterface
{
Q_OBJECT
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
Q_INTERFACES(QMediaServiceFeaturesInterface)
// The player service provided by the WMF-plugin should preferably be used.
// DirectShow should then only provide the camera (see QTBUG-29172, QTBUG-29175).
@@ -68,6 +70,7 @@ public:
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
QByteArray defaultDevice(const QByteArray &service) const;
QList<QByteArray> devices(const QByteArray &service) const;
QString deviceDescription(const QByteArray &service, const QByteArray &device);
@@ -75,6 +78,7 @@ private:
#ifdef QMEDIA_DIRECTSHOW_CAMERA
void updateDevices() const;
mutable QByteArray m_defaultCameraDevice;
mutable QList<QByteArray> m_cameraDevices;
mutable QStringList m_cameraDescriptions;
#endif

View File

@@ -90,6 +90,18 @@ QMediaServiceProviderHint::Features CameraBinServicePlugin::supportedFeatures(
return QMediaServiceProviderHint::Features();
}
QByteArray CameraBinServicePlugin::defaultDevice(const QByteArray &service) const
{
if (service == Q_MEDIASERVICE_CAMERA) {
if (m_cameraDevices.isEmpty())
updateDevices();
return m_defaultCameraDevice;
}
return QByteArray();
}
QList<QByteArray> CameraBinServicePlugin::devices(const QByteArray &service) const
{
if (service == Q_MEDIASERVICE_CAMERA) {
@@ -126,6 +138,7 @@ QVariant CameraBinServicePlugin::deviceProperty(const QByteArray &service, const
void CameraBinServicePlugin::updateDevices() const
{
m_defaultCameraDevice.clear();
m_cameraDevices.clear();
m_cameraDescriptions.clear();
@@ -167,6 +180,9 @@ void CameraBinServicePlugin::updateDevices() const
}
::close(fd);
}
if (!m_cameraDevices.isEmpty())
m_defaultCameraDevice = m_cameraDevices.first();
}
QT_END_NAMESPACE

View File

@@ -51,10 +51,12 @@ QT_BEGIN_NAMESPACE
class CameraBinServicePlugin
: public QMediaServiceProviderPlugin
, public QMediaServiceSupportedDevicesInterface
, public QMediaServiceDefaultDeviceInterface
, public QMediaServiceFeaturesInterface
{
Q_OBJECT
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
Q_INTERFACES(QMediaServiceFeaturesInterface)
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "camerabin.json")
public:
@@ -63,6 +65,7 @@ public:
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
QByteArray defaultDevice(const QByteArray &service) const;
QList<QByteArray> devices(const QByteArray &service) const;
QString deviceDescription(const QByteArray &service, const QByteArray &device);
QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property);
@@ -70,6 +73,7 @@ public:
private:
void updateDevices() const;
mutable QByteArray m_defaultCameraDevice;
mutable QList<QByteArray> m_cameraDevices;
mutable QStringList m_cameraDescriptions;
};

View File

@@ -95,6 +95,18 @@ QMediaServiceProviderHint::Features QGstreamerCaptureServicePlugin::supportedFea
return QMediaServiceProviderHint::Features();
}
QByteArray QGstreamerCaptureServicePlugin::defaultDevice(const QByteArray &service) const
{
if (service == Q_MEDIASERVICE_CAMERA) {
if (m_cameraDevices.isEmpty())
updateDevices();
return m_defaultCameraDevice;
}
return QByteArray();
}
QList<QByteArray> QGstreamerCaptureServicePlugin::devices(const QByteArray &service) const
{
if (service == Q_MEDIASERVICE_CAMERA) {
@@ -131,6 +143,7 @@ QVariant QGstreamerCaptureServicePlugin::deviceProperty(const QByteArray &servic
void QGstreamerCaptureServicePlugin::updateDevices() const
{
m_defaultCameraDevice.clear();
m_cameraDevices.clear();
m_cameraDescriptions.clear();
@@ -174,6 +187,9 @@ void QGstreamerCaptureServicePlugin::updateDevices() const
}
::close(fd);
}
if (!m_cameraDevices.isEmpty())
m_defaultCameraDevice = m_cameraDevices.first();
}
#endif

View File

@@ -53,6 +53,7 @@ class QGstreamerCaptureServicePlugin
: public QMediaServiceProviderPlugin
#if defined(USE_GSTREAMER_CAMERA)
, public QMediaServiceSupportedDevicesInterface
, public QMediaServiceDefaultDeviceInterface
, public QMediaServiceFeaturesInterface
#endif
, public QMediaServiceSupportedFormatsInterface
@@ -60,6 +61,7 @@ class QGstreamerCaptureServicePlugin
Q_OBJECT
#if defined(USE_GSTREAMER_CAMERA)
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
Q_INTERFACES(QMediaServiceFeaturesInterface)
#endif
Q_INTERFACES(QMediaServiceSupportedFormatsInterface)
@@ -75,6 +77,7 @@ public:
#if defined(USE_GSTREAMER_CAMERA)
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
QByteArray defaultDevice(const QByteArray &service) const;
QList<QByteArray> devices(const QByteArray &service) const;
QString deviceDescription(const QByteArray &service, const QByteArray &device);
QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property);
@@ -87,6 +90,7 @@ private:
#if defined(USE_GSTREAMER_CAMERA)
void updateDevices() const;
mutable QByteArray m_defaultCameraDevice;
mutable QList<QByteArray> m_cameraDevices;
mutable QStringList m_cameraDescriptions;
#endif

View File

@@ -74,6 +74,18 @@ QMediaServiceProviderHint::Features BbServicePlugin::supportedFeatures(const QBy
return QMediaServiceProviderHint::Features();
}
QByteArray BbServicePlugin::defaultDevice(const QByteArray &service) const
{
if (service == Q_MEDIASERVICE_CAMERA) {
if (m_cameraDevices.isEmpty())
updateDevices();
return m_defaultCameraDevice;
}
return QByteArray();
}
QList<QByteArray> BbServicePlugin::devices(const QByteArray &service) const
{
if (service == Q_MEDIASERVICE_CAMERA) {
@@ -102,10 +114,13 @@ QString BbServicePlugin::deviceDescription(const QByteArray &service, const QByt
void BbServicePlugin::updateDevices() const
{
m_defaultCameraDevice.clear();
BbVideoDeviceSelectorControl::enumerateDevices(&m_cameraDevices, &m_cameraDescriptions);
if (m_cameraDevices.isEmpty()) {
qWarning() << "No camera devices found";
} else {
m_defaultCameraDevice = m_cameraDevices.first();
}
}

View File

@@ -48,10 +48,12 @@ QT_BEGIN_NAMESPACE
class BbServicePlugin
: public QMediaServiceProviderPlugin,
public QMediaServiceSupportedDevicesInterface,
public QMediaServiceDefaultDeviceInterface,
public QMediaServiceFeaturesInterface
{
Q_OBJECT
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
Q_INTERFACES(QMediaServiceFeaturesInterface)
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "blackberry_mediaservice.json")
public:
@@ -61,6 +63,7 @@ public:
void release(QMediaService *service) Q_DECL_OVERRIDE;
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const Q_DECL_OVERRIDE;
QByteArray defaultDevice(const QByteArray &service) const Q_DECL_OVERRIDE;
QList<QByteArray> devices(const QByteArray &service) const Q_DECL_OVERRIDE;
QString deviceDescription(const QByteArray &service, const QByteArray &device) Q_DECL_OVERRIDE;
QVariant deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property) Q_DECL_OVERRIDE;
@@ -68,6 +71,7 @@ public:
private:
void updateDevices() const;
mutable QByteArray m_defaultCameraDevice;
mutable QList<QByteArray> m_cameraDevices;
mutable QStringList m_cameraDescriptions;
};

View File

@@ -105,6 +105,11 @@ QMediaServiceProviderHint::Features WMFServicePlugin::supportedFeatures(
return QMediaServiceProviderHint::Features();
}
QByteArray WMFServicePlugin::defaultDevice(const QByteArray &) const
{
return QByteArray();
}
QList<QByteArray> WMFServicePlugin::devices(const QByteArray &) const
{
return QList<QByteArray>();

View File

@@ -49,10 +49,12 @@ QT_USE_NAMESPACE
class WMFServicePlugin
: public QMediaServiceProviderPlugin
, public QMediaServiceSupportedDevicesInterface
, public QMediaServiceDefaultDeviceInterface
, public QMediaServiceFeaturesInterface
{
Q_OBJECT
Q_INTERFACES(QMediaServiceSupportedDevicesInterface)
Q_INTERFACES(QMediaServiceDefaultDeviceInterface)
Q_INTERFACES(QMediaServiceFeaturesInterface)
Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "wmf.json")
public:
@@ -61,6 +63,7 @@ public:
QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const;
QByteArray defaultDevice(const QByteArray &service) const;
QList<QByteArray> devices(const QByteArray &service) const;
QString deviceDescription(const QByteArray &service, const QByteArray &device);
};