diff options
Diffstat (limited to 'src/plugins/avfoundation')
4 files changed, 59 insertions, 38 deletions
diff --git a/src/plugins/avfoundation/camera/avfcameradevicecontrol.mm b/src/plugins/avfoundation/camera/avfcameradevicecontrol.mm index 7e0d6fb4b..80347ed93 100644 --- a/src/plugins/avfoundation/camera/avfcameradevicecontrol.mm +++ b/src/plugins/avfoundation/camera/avfcameradevicecontrol.mm @@ -58,25 +58,25 @@ int AVFCameraDeviceControl::deviceCount() const QString AVFCameraDeviceControl::deviceName(int index) const { - const QList<QByteArray> &devices = AVFCameraSession::availableCameraDevices(); + const QList<AVFCameraInfo> &devices = AVFCameraSession::availableCameraDevices(); if (index < 0 || index >= devices.count()) return QString(); - return QString::fromUtf8(devices.at(index)); + return QString::fromUtf8(devices.at(index).deviceId); } QString AVFCameraDeviceControl::deviceDescription(int index) const { - const QList<QByteArray> &devices = AVFCameraSession::availableCameraDevices(); + const QList<AVFCameraInfo> &devices = AVFCameraSession::availableCameraDevices(); if (index < 0 || index >= devices.count()) return QString(); - return AVFCameraSession::cameraDeviceInfo(devices.at(index)).description; + return devices.at(index).description; } int AVFCameraDeviceControl::defaultDevice() const { - return AVFCameraSession::availableCameraDevices().indexOf(AVFCameraSession::defaultCameraDevice()); + return AVFCameraSession::defaultCameraIndex(); } int AVFCameraDeviceControl::selectedDevice() const diff --git a/src/plugins/avfoundation/camera/avfcameraserviceplugin.mm b/src/plugins/avfoundation/camera/avfcameraserviceplugin.mm index 551ff1bb3..bf2f4a24b 100644 --- a/src/plugins/avfoundation/camera/avfcameraserviceplugin.mm +++ b/src/plugins/avfoundation/camera/avfcameraserviceplugin.mm @@ -63,18 +63,26 @@ void AVFServicePlugin::release(QMediaService *service) QByteArray AVFServicePlugin::defaultDevice(const QByteArray &service) const { - if (service == Q_MEDIASERVICE_CAMERA) - return AVFCameraSession::defaultCameraDevice(); + if (service == Q_MEDIASERVICE_CAMERA) { + int i = AVFCameraSession::defaultCameraIndex(); + if (i != -1) + return AVFCameraSession::availableCameraDevices().at(i).deviceId; + } return QByteArray(); } QList<QByteArray> AVFServicePlugin::devices(const QByteArray &service) const { - if (service == Q_MEDIASERVICE_CAMERA) - return AVFCameraSession::availableCameraDevices(); + QList<QByteArray> devs; + + if (service == Q_MEDIASERVICE_CAMERA) { + const QList<AVFCameraInfo> &cameras = AVFCameraSession::availableCameraDevices(); + Q_FOREACH (const AVFCameraInfo &info, cameras) + devs.append(info.deviceId); + } - return QList<QByteArray>(); + return devs; } QString AVFServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) diff --git a/src/plugins/avfoundation/camera/avfcamerasession.h b/src/plugins/avfoundation/camera/avfcamerasession.h index 9fd0b1828..4772351e6 100644 --- a/src/plugins/avfoundation/camera/avfcamerasession.h +++ b/src/plugins/avfoundation/camera/avfcamerasession.h @@ -54,6 +54,7 @@ struct AVFCameraInfo AVFCameraInfo() : position(QCamera::UnspecifiedPosition), orientation(0) { } + QByteArray deviceId; QString description; QCamera::Position position; int orientation; @@ -66,8 +67,8 @@ public: AVFCameraSession(AVFCameraService *service, QObject *parent = 0); ~AVFCameraSession(); - static const QByteArray &defaultCameraDevice(); - static const QList<QByteArray> &availableCameraDevices(); + static int defaultCameraIndex(); + static const QList<AVFCameraInfo> &availableCameraDevices(); static AVFCameraInfo cameraDeviceInfo(const QByteArray &device); void setVideoOutput(AVFCameraRendererControl *output); @@ -102,9 +103,8 @@ private: void applyImageEncoderSettings(); void applyViewfinderSettings(); - static QByteArray m_defaultCameraDevice; - static QList<QByteArray> m_cameraDevices; - static QMap<QByteArray, AVFCameraInfo> m_cameraInfo; + static int m_defaultCameraIndex; + static QList<AVFCameraInfo> m_cameraDevices; AVFCameraService *m_service; AVFCameraRendererControl *m_videoOutput; diff --git a/src/plugins/avfoundation/camera/avfcamerasession.mm b/src/plugins/avfoundation/camera/avfcamerasession.mm index af30dd312..48fe428d8 100644 --- a/src/plugins/avfoundation/camera/avfcamerasession.mm +++ b/src/plugins/avfoundation/camera/avfcamerasession.mm @@ -48,14 +48,14 @@ #include <QtCore/qdatetime.h> #include <QtCore/qurl.h> +#include <QtCore/qelapsedtimer.h> #include <QtCore/qdebug.h> QT_USE_NAMESPACE -QByteArray AVFCameraSession::m_defaultCameraDevice; -QList<QByteArray> AVFCameraSession::m_cameraDevices; -QMap<QByteArray, AVFCameraInfo> AVFCameraSession::m_cameraInfo; +int AVFCameraSession::m_defaultCameraIndex; +QList<AVFCameraInfo> AVFCameraSession::m_cameraDevices; @interface AVFCameraSessionObserver : NSObject { @@ -169,45 +169,55 @@ AVFCameraSession::~AVFCameraSession() [m_captureSession release]; } -const QByteArray &AVFCameraSession::defaultCameraDevice() +int AVFCameraSession::defaultCameraIndex() { - if (m_cameraDevices.isEmpty()) - updateCameraDevices(); - - return m_defaultCameraDevice; + updateCameraDevices(); + return m_defaultCameraIndex; } -const QList<QByteArray> &AVFCameraSession::availableCameraDevices() +const QList<AVFCameraInfo> &AVFCameraSession::availableCameraDevices() { - if (m_cameraDevices.isEmpty()) - updateCameraDevices(); - + updateCameraDevices(); return m_cameraDevices; } AVFCameraInfo AVFCameraSession::cameraDeviceInfo(const QByteArray &device) { - if (m_cameraDevices.isEmpty()) - updateCameraDevices(); + updateCameraDevices(); + + Q_FOREACH (const AVFCameraInfo &info, m_cameraDevices) { + if (info.deviceId == device) + return info; + } - return m_cameraInfo.value(device); + return AVFCameraInfo(); } void AVFCameraSession::updateCameraDevices() { - m_defaultCameraDevice.clear(); +#ifdef Q_OS_IOS + // Cameras can't change dynamically on iOS. Update only once. + if (!m_cameraDevices.isEmpty()) + return; +#else + // On OS X, cameras can be added or removed. Update the list every time, but not more than + // once every 500 ms + static QElapsedTimer timer; + if (timer.isValid() && timer.elapsed() < 500) // ms + return; +#endif + + m_defaultCameraIndex = -1; m_cameraDevices.clear(); - m_cameraInfo.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]); + if (defaultDevice && [defaultDevice.uniqueID isEqualToString:device.uniqueID]) + m_defaultCameraIndex = m_cameraDevices.count(); AVFCameraInfo info; + info.deviceId = QByteArray([[device uniqueID] UTF8String]); info.description = QString::fromNSString([device localizedName]); // There is no API to get the camera sensor orientation, however, cameras are always @@ -232,9 +242,12 @@ void AVFCameraSession::updateCameraDevices() break; } - m_cameraDevices << deviceId; - m_cameraInfo.insert(deviceId, info); + m_cameraDevices.append(info); } + +#ifndef Q_OS_IOS + timer.restart(); +#endif } void AVFCameraSession::setVideoOutput(AVFCameraRendererControl *output) |