diff options
26 files changed, 322 insertions, 177 deletions
diff --git a/cmake/FindGSTREAMER.cmake b/cmake/FindGStreamer.cmake index ef9edd485..ef9edd485 100644 --- a/cmake/FindGSTREAMER.cmake +++ b/cmake/FindGStreamer.cmake diff --git a/src/imports/multimedia/qdeclarativecamera.cpp b/src/imports/multimedia/qdeclarativecamera.cpp index d07f0015f..9c4004ef6 100644 --- a/src/imports/multimedia/qdeclarativecamera.cpp +++ b/src/imports/multimedia/qdeclarativecamera.cpp @@ -296,13 +296,13 @@ QDeclarativeCamera::Position QDeclarativeCamera::position() const void QDeclarativeCamera::setPosition(Position position) { - QCamera::Position pos = QCamera::Position(position); + QCameraInfo::Position pos = QCameraInfo::Position(position); if (pos == m_currentCameraInfo.position()) return; QByteArray id; - if (pos != QCamera::UnspecifiedPosition) { + if (pos != QCameraInfo::UnspecifiedPosition) { const QList<QCameraInfo> cameras = QMediaDeviceManager::videoInputs(); for (auto c : cameras) { if (c.position() == pos) { @@ -354,11 +354,6 @@ QString QDeclarativeCamera::displayName() const \since 5.4 */ -int QDeclarativeCamera::orientation() const -{ - return m_currentCameraInfo.orientation(); -} - void QDeclarativeCamera::setupDevice(const QString &deviceName) { QCameraInfo oldCameraInfo = m_currentCameraInfo; @@ -383,8 +378,6 @@ void QDeclarativeCamera::setupDevice(const QString &deviceName) emit displayNameChanged(); if (oldCameraInfo.position() != m_currentCameraInfo.position()) emit positionChanged(); - if (oldCameraInfo.orientation() != m_currentCameraInfo.orientation()) - emit orientationChanged(); setCameraState(previousState); } diff --git a/src/imports/multimedia/qdeclarativecamera_p.h b/src/imports/multimedia/qdeclarativecamera_p.h index f2cb38b51..6faa461f6 100644 --- a/src/imports/multimedia/qdeclarativecamera_p.h +++ b/src/imports/multimedia/qdeclarativecamera_p.h @@ -82,7 +82,6 @@ class QDeclarativeCamera : public QObject, public QQmlParserStatus Q_PROPERTY(QString deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged REVISION 1) Q_PROPERTY(Position position READ position WRITE setPosition NOTIFY positionChanged REVISION 1) Q_PROPERTY(QString displayName READ displayName NOTIFY displayNameChanged REVISION 1) - Q_PROPERTY(int orientation READ orientation NOTIFY orientationChanged REVISION 1) Q_PROPERTY(CaptureMode captureMode READ captureMode WRITE setCaptureMode NOTIFY captureModeChanged) Q_PROPERTY(State cameraState READ cameraState WRITE setCameraState NOTIFY cameraStateChanged) @@ -123,9 +122,9 @@ class QDeclarativeCamera : public QObject, public QQmlParserStatus public: enum Position { - UnspecifiedPosition = QCamera::UnspecifiedPosition, - BackFace = QCamera::BackFace, - FrontFace = QCamera::FrontFace + UnspecifiedPosition = QCameraInfo::UnspecifiedPosition, + BackFace = QCameraInfo::BackFace, + FrontFace = QCameraInfo::FrontFace }; enum CaptureMode { @@ -256,7 +255,6 @@ public: void setPosition(Position position); QString displayName() const; - int orientation() const; CaptureMode captureMode() const; State cameraState() const; @@ -301,7 +299,6 @@ Q_SIGNALS: Q_REVISION(1) void deviceIdChanged(); Q_REVISION(1) void positionChanged(); Q_REVISION(1) void displayNameChanged(); - Q_REVISION(1) void orientationChanged(); void captureModeChanged(); void cameraStateChanged(QDeclarativeCamera::State); diff --git a/src/imports/multimedia/qdeclarativemultimediaglobal.cpp b/src/imports/multimedia/qdeclarativemultimediaglobal.cpp index 5e851ab79..d678e07dc 100644 --- a/src/imports/multimedia/qdeclarativemultimediaglobal.cpp +++ b/src/imports/multimedia/qdeclarativemultimediaglobal.cpp @@ -160,7 +160,7 @@ static QJSValue cameraInfoToJSValue(QJSEngine *jsEngine, const QCameraInfo &came o.setProperty(QStringLiteral("deviceId"), QString::fromLatin1(camera.id())); o.setProperty(QStringLiteral("displayName"), camera.description()); o.setProperty(QStringLiteral("position"), int(camera.position())); - o.setProperty(QStringLiteral("orientation"), camera.orientation()); + // ### Add resolutions and framerates return o; } diff --git a/src/multimedia/camera/qcamera.cpp b/src/multimedia/camera/qcamera.cpp index b9e4b8f53..bc158969f 100644 --- a/src/multimedia/camera/qcamera.cpp +++ b/src/multimedia/camera/qcamera.cpp @@ -63,7 +63,7 @@ static void qRegisterCameraMetaTypes() qRegisterMetaType<QCamera::LockType>("QCamera::LockType"); qRegisterMetaType<QCamera::LockStatus>("QCamera::LockStatus"); qRegisterMetaType<QCamera::LockChangeReason>("QCamera::LockChangeReason"); - qRegisterMetaType<QCamera::Position>("QCamera::Position"); + qRegisterMetaType<QCameraInfo::Position>("QCameraInfo::Position"); } Q_CONSTRUCTOR_FUNCTION(qRegisterCameraMetaTypes) @@ -314,10 +314,10 @@ QCamera::QCamera(const QCameraInfo &cameraInfo, QObject *parent) back-facing cameras. If no camera is available at the specified \a position or if \a position is - QCamera::UnspecifiedPosition, the default camera is used. + QCameraInfo::UnspecifiedPosition, the default camera is used. */ -QCamera::QCamera(QCamera::Position position, QObject *parent) +QCamera::QCamera(QCameraInfo::Position position, QObject *parent) : QMediaSource(*new QCameraPrivate, parent, QMediaPlatformIntegration::instance()->createCaptureInterface(QMediaRecorder::AudioAndVideo)) @@ -1118,7 +1118,7 @@ void QCamera::unlock() */ /*! - \enum QCamera::Position + \enum QCameraInfo::Position \since 5.3 This enum specifies the physical position of the camera on the system hardware. diff --git a/src/multimedia/camera/qcamera.h b/src/multimedia/camera/qcamera.h index 9829e3ac2..80ebe88eb 100644 --- a/src/multimedia/camera/qcamera.h +++ b/src/multimedia/camera/qcamera.h @@ -52,6 +52,7 @@ #include <QtMultimedia/qcamerafocus.h> #include <QtMultimedia/qcameraimageprocessing.h> #include <QtMultimedia/qcameraviewfindersettings.h> +#include <QtMultimedia/qcamerainfo.h> #include <QtMultimedia/qmediaenumdebug.h> @@ -151,16 +152,9 @@ public: }; Q_DECLARE_FLAGS(LockTypes, LockType) - enum Position - { - UnspecifiedPosition, - BackFace, - FrontFace - }; - explicit QCamera(QObject *parent = nullptr); explicit QCamera(const QCameraInfo& cameraInfo, QObject *parent = nullptr); - explicit QCamera(QCamera::Position position, QObject *parent = nullptr); + explicit QCamera(QCameraInfo::Position position, QObject *parent = nullptr); ~QCamera(); QMultimedia::AvailabilityStatus availability() const override; @@ -273,7 +267,6 @@ Q_DECLARE_METATYPE(QCamera::CaptureModes) Q_DECLARE_METATYPE(QCamera::LockType) Q_DECLARE_METATYPE(QCamera::LockStatus) Q_DECLARE_METATYPE(QCamera::LockChangeReason) -Q_DECLARE_METATYPE(QCamera::Position) Q_MEDIA_ENUM_DEBUG(QCamera, State) Q_MEDIA_ENUM_DEBUG(QCamera, Status) @@ -282,6 +275,5 @@ Q_MEDIA_ENUM_DEBUG(QCamera, CaptureMode) Q_MEDIA_ENUM_DEBUG(QCamera, LockType) Q_MEDIA_ENUM_DEBUG(QCamera, LockStatus) Q_MEDIA_ENUM_DEBUG(QCamera, LockChangeReason) -Q_MEDIA_ENUM_DEBUG(QCamera, Position) #endif // QCAMERA_H diff --git a/src/multimedia/camera/qcamera_p.h b/src/multimedia/camera/qcamera_p.h index ea9926ca4..de10b7d9a 100644 --- a/src/multimedia/camera/qcamera_p.h +++ b/src/multimedia/camera/qcamera_p.h @@ -64,21 +64,21 @@ class QCameraPrivate : public QMediaSourcePrivate { Q_DECLARE_NON_CONST_PUBLIC(QCamera) public: - QCameraPrivate(): - QMediaSourcePrivate(), - control(nullptr), - cameraExposure(nullptr), - cameraFocus(nullptr), - imageProcessing(nullptr), - viewfinder(nullptr), - capture(nullptr), - state(QCamera::UnloadedState), - error(QCamera::NoError), - requestedLocks(QCamera::NoLock), - lockStatus(QCamera::Unlocked), - lockChangeReason(QCamera::UserRequest), - supressLockChangedSignal(false), - restartPending(false) + QCameraPrivate() + : QMediaSourcePrivate(), + control(nullptr), + cameraExposure(nullptr), + cameraFocus(nullptr), + imageProcessing(nullptr), + viewfinder(nullptr), + capture(nullptr), + state(QCamera::UnloadedState), + error(QCamera::NoError), + requestedLocks(QCamera::NoLock), + lockStatus(QCamera::Unlocked), + lockChangeReason(QCamera::UserRequest), + supressLockChangedSignal(false), + restartPending(false) { } diff --git a/src/multimedia/camera/qcamerainfo.cpp b/src/multimedia/camera/qcamerainfo.cpp index 4946142c2..571b749b0 100644 --- a/src/multimedia/camera/qcamerainfo.cpp +++ b/src/multimedia/camera/qcamerainfo.cpp @@ -43,6 +43,46 @@ QT_BEGIN_NAMESPACE +QCameraFormat::QCameraFormat(const QCameraFormat &other) + : d(other.d) +{ +} + +QCameraFormat &QCameraFormat::operator=(const QCameraFormat &other) +{ + d = other.d; + return *this; +} + +QCameraFormat::~QCameraFormat() +{ +} + +QVideoFrame::PixelFormat QCameraFormat::pixelFormat() const +{ + return d->pixelFormat; +} + +QSize QCameraFormat::resolution() const +{ + return d->resolution; +} + +float QCameraFormat::minFrameRate() const +{ + return d->minFrameRate; +} + +float QCameraFormat::maxFrameRate() const +{ + return d->maxFrameRate; +} + +QCameraFormat::QCameraFormat(QCameraFormatPrivate *p) + : d(p) +{ +} + /*! \class QCameraInfo \brief The QCameraInfo class provides general information about camera devices. @@ -76,19 +116,6 @@ QT_BEGIN_NAMESPACE QCameraInfo::QCameraInfo() = default; /*! - Constructs a camera info object for \a camera. - - You can use it to query information about the \a camera object passed as argument. - - If the \a camera is invalid, for example when no camera device is available on the system, - the QCameraInfo object will be invalid and isNull() will return true. -*/ -QCameraInfo::QCameraInfo(const QCamera &camera) - : QCameraInfo(camera.cameraInfo()) -{ -} - -/*! Constructs a copy of \a other. */ QCameraInfo::QCameraInfo(const QCameraInfo &other) @@ -116,8 +143,7 @@ bool QCameraInfo::operator==(const QCameraInfo &other) const return (d->id == other.d->id && d->description == other.d->description - && d->position == other.d->position - && d->orientation == other.d->orientation); + && d->position == other.d->position); } /*! @@ -154,28 +180,22 @@ QString QCameraInfo::description() const /*! Returns the physical position of the camera on the hardware system. */ -QCamera::Position QCameraInfo::position() const +QCameraInfo::Position QCameraInfo::position() const { - return d ? d->position : QCamera::UnspecifiedPosition; + return d ? d->position : QCameraInfo::UnspecifiedPosition; } -/*! - Returns the physical orientation of the camera sensor. - - The value is the orientation angle (clockwise, in steps of 90 degrees) of the camera sensor - in relation to the display in its natural orientation. - - You can show the camera image in the correct orientation by rotating it by this value in the - anti-clockwise direction. +QList<QSize> QCameraInfo::photoResolutions() const +{ + return d->photoResolutions; +} - For example, suppose a mobile device which is naturally in portrait orientation. The back-facing - camera is mounted in landscape. If the top side of the camera sensor is aligned with the - right edge of the screen in natural orientation, the value should be 270. If the top side of a - front-facing camera sensor is aligned with the right of the screen, the value should be 90. +/*! + Returns the video formats supported by the camera. */ -int QCameraInfo::orientation() const +QList<QCameraFormat> QCameraInfo::videoFormats() const { - return d ? d->orientation : 0; + return d ? d->videoFormats : QList<QCameraFormat>{}; } QCameraInfo::QCameraInfo(QCameraInfoPrivate *p) @@ -203,8 +223,7 @@ QDebug operator<<(QDebug d, const QCameraInfo &camera) d.maybeSpace() << QStringLiteral("QCameraInfo(name=%1, position=%2, orientation=%3)") .arg(camera.description()) .arg(QString::fromLatin1(QCamera::staticMetaObject.enumerator(QCamera::staticMetaObject.indexOfEnumerator("Position")) - .valueToKey(camera.position()))) - .arg(camera.orientation()); + .valueToKey(camera.position()))); return d.space(); } #endif diff --git a/src/multimedia/camera/qcamerainfo.h b/src/multimedia/camera/qcamerainfo.h index 8b640410a..afe9965a6 100644 --- a/src/multimedia/camera/qcamerainfo.h +++ b/src/multimedia/camera/qcamerainfo.h @@ -40,36 +40,71 @@ #ifndef QCAMERAINFO_H #define QCAMERAINFO_H -#include <QtMultimedia/qcamera.h> +#include <QtMultimedia/qvideoframe.h> #include <QtCore/qsharedpointer.h> QT_BEGIN_NAMESPACE -class QCameraInfoPrivate; +class QCameraFormatPrivate; +class Q_MULTIMEDIA_EXPORT QCameraFormat +{ +public: + QCameraFormat() = delete; + QCameraFormat(const QCameraFormat &other); + QCameraFormat &operator=(const QCameraFormat &other); + ~QCameraFormat(); + + QVideoFrame::PixelFormat pixelFormat() const; + QSize resolution() const; + float minFrameRate() const; + float maxFrameRate() const; + +private: + friend class QCameraFormatPrivate; + QCameraFormat(QCameraFormatPrivate *p); + QExplicitlySharedDataPointer<QCameraFormatPrivate> d; +}; +class QCameraInfoPrivate; class Q_MULTIMEDIA_EXPORT QCameraInfo { public: QCameraInfo(); - explicit QCameraInfo(const QCamera &camera); QCameraInfo(const QCameraInfo& other); + QCameraInfo& operator=(const QCameraInfo& other); ~QCameraInfo(); - QCameraInfo& operator=(const QCameraInfo& other); bool operator==(const QCameraInfo &other) const; inline bool operator!=(const QCameraInfo &other) const; bool isNull() const; QByteArray id() const; + QString description() const; + + // ### Add here and to QAudioDeviceInfo +// QByteArray groupId() const; +// QString groupDescription() const; + bool isDefault() const; - QString description() const; - QCamera::Position position() const; - int orientation() const; + enum Position + { + UnspecifiedPosition, + BackFace, + FrontFace + }; + + Position position() const; + + QList<QSize> photoResolutions() const; + QList<QCameraFormat> videoFormats() const; + + // ### Add zoom and other camera information - QCameraInfo(QCameraInfoPrivate *p); private: + friend class QCameraInfoPrivate; + QCameraInfo(QCameraInfoPrivate *p); QExplicitlySharedDataPointer<QCameraInfoPrivate> d; }; diff --git a/src/multimedia/camera/qcamerainfo_p.h b/src/multimedia/camera/qcamerainfo_p.h index 377a418e3..710bd0971 100644 --- a/src/multimedia/camera/qcamerainfo_p.h +++ b/src/multimedia/camera/qcamerainfo_p.h @@ -56,14 +56,29 @@ QT_BEGIN_NAMESPACE +class QCameraFormatPrivate : public QSharedData +{ +public: + QVideoFrame::PixelFormat pixelFormat; + QSize resolution; + float minFrameRate = 0; + float maxFrameRate = 0; + + QCameraFormat create() { return QCameraFormat(this); } +}; + class QCameraInfoPrivate : public QSharedData { public: QByteArray id; QString description; bool isDefault = false; - QCamera::Position position = QCamera::UnspecifiedPosition; + QCameraInfo::Position position = QCameraInfo::UnspecifiedPosition; int orientation = 0; + QList<QSize> photoResolutions; + QList<QCameraFormat> videoFormats; + + QCameraInfo create() { return QCameraInfo(this); } }; QT_END_NAMESPACE diff --git a/src/multimedia/doc/snippets/multimedia-snippets/camera.cpp b/src/multimedia/doc/snippets/multimedia-snippets/camera.cpp index f851caadd..d6c6488d2 100644 --- a/src/multimedia/doc/snippets/multimedia-snippets/camera.cpp +++ b/src/multimedia/doc/snippets/multimedia-snippets/camera.cpp @@ -82,7 +82,7 @@ void overview_viewfinder() void overview_camera_by_position() { //! [Camera overview position] - camera = new QCamera(QCamera::FrontFace); + camera = new QCamera(QCameraInfo::FrontFace); //! [Camera overview position] } @@ -128,7 +128,7 @@ void overview_viewfinder_orientation() const int screenAngle = screen->angleBetween(screen->nativeOrientation(), screen->orientation()); int rotation; - if (cameraInfo.position() == QCamera::BackFace) { + if (cameraInfo.position() == QCameraInfo::BackFace) { rotation = (cameraInfo.orientation() - screenAngle) % 360; } else { // Front position, compensate the mirror @@ -202,9 +202,9 @@ void camera_info() QCamera myCamera; QCameraInfo cameraInfo(myCamera); - if (cameraInfo.position() == QCamera::FrontFace) + if (cameraInfo.position() == QCameraInfo::FrontFace) qDebug() << "The camera is on the front face of the hardware system."; - else if (cameraInfo.position() == QCamera::BackFace) + else if (cameraInfo.position() == QCameraInfo::BackFace) qDebug() << "The camera is on the back face of the hardware system."; qDebug() << "The camera sensor orientation is " << cameraInfo.orientation() << " degrees."; diff --git a/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp b/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp index b609314a7..a9829ce4b 100644 --- a/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp +++ b/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp @@ -165,7 +165,7 @@ void QAndroidCameraSession::updateAvailableCameras() AndroidCamera::getCameraInfo(i, info); if (!info->id.isEmpty()) - g_availableCameras->append(QCameraInfo(info)); + g_availableCameras->append(info->create()); } } diff --git a/src/multimedia/platform/android/wrappers/jni/androidcamera.cpp b/src/multimedia/platform/android/wrappers/jni/androidcamera.cpp index 41e1fcf20..e7ca0e578 100644 --- a/src/multimedia/platform/android/wrappers/jni/androidcamera.cpp +++ b/src/multimedia/platform/android/wrappers/jni/androidcamera.cpp @@ -787,13 +787,13 @@ void AndroidCamera::getCameraInfo(int id, QCameraInfoPrivate *info) case AndroidCamera::CameraFacingBack: info->id = QByteArray("back"); info->description = QStringLiteral("Rear-facing camera"); - info->position = QCamera::BackFace; + info->position = QCameraInfo::BackFace; info->isDefault = true; break; case AndroidCamera::CameraFacingFront: info->id = QByteArray("front"); info->description = QStringLiteral("Front-facing camera"); - info->position = QCamera::FrontFace; + info->position = QCameraInfo::FrontFace; break; default: break; diff --git a/src/multimedia/platform/darwin/camera/avfcameracontrol.mm b/src/multimedia/platform/darwin/camera/avfcameracontrol.mm index 31de25d08..d340696f2 100644 --- a/src/multimedia/platform/darwin/camera/avfcameracontrol.mm +++ b/src/multimedia/platform/darwin/camera/avfcameracontrol.mm @@ -309,6 +309,9 @@ QVideoFrame::PixelFormat AVFCameraControl::QtPixelFormatFromCVFormat(unsigned av return QVideoFrame::Format_UYVY; case kCVPixelFormatType_422YpCbCr8_yuvs: return QVideoFrame::Format_YUYV; + case kCMVideoCodecType_JPEG: + case kCMVideoCodecType_JPEG_OpenDML: + return QVideoFrame::Format_Jpeg; default: return QVideoFrame::Format_Invalid; } diff --git a/src/multimedia/platform/darwin/camera/avfcamerasession_p.h b/src/multimedia/platform/darwin/camera/avfcamerasession_p.h index 4ea8cb9b5..584bd9b1b 100644 --- a/src/multimedia/platform/darwin/camera/avfcamerasession_p.h +++ b/src/multimedia/platform/darwin/camera/avfcamerasession_p.h @@ -70,12 +70,12 @@ class AVFCameraWindowControl; struct AVFCameraInfo { - AVFCameraInfo() : position(QCamera::UnspecifiedPosition), orientation(0) + AVFCameraInfo() : position(QCameraInfo::UnspecifiedPosition), orientation(0) { } QByteArray deviceId; QString description; - QCamera::Position position; + QCameraInfo::Position position; int orientation; }; diff --git a/src/multimedia/platform/darwin/camera/avfmediarecordercontrol_ios.mm b/src/multimedia/platform/darwin/camera/avfmediarecordercontrol_ios.mm index 666278a40..22989953f 100644 --- a/src/multimedia/platform/darwin/camera/avfmediarecordercontrol_ios.mm +++ b/src/multimedia/platform/darwin/camera/avfmediarecordercontrol_ios.mm @@ -269,10 +269,11 @@ void AVFMediaRecorderControlIOS::setState(QMediaRecorder::State state) QCameraInfo cameraInfo = m_service->session()->activeCameraInfo(); int screenOrientation = 360 - m_orientationHandler.currentOrientation(); float rotation = 0; - if (cameraInfo.position() == QCamera::FrontFace) - rotation = (screenOrientation + cameraInfo.orientation()) % 360; - else - rotation = (screenOrientation + (360 - cameraInfo.orientation())) % 360; + // ### +// if (cameraInfo.position() == QCameraInfo::FrontFace) +// rotation = (screenOrientation + cameraInfo.orientation()) % 360; +// else +// rotation = (screenOrientation + (360 - cameraInfo.orientation())) % 360; if ([m_writer setupWithFileURL:nsFileURL cameraService:m_service diff --git a/src/multimedia/platform/darwin/qdarwindevicemanager.mm b/src/multimedia/platform/darwin/qdarwindevicemanager.mm index 4e4642a3c..1a483dd72 100644 --- a/src/multimedia/platform/darwin/qdarwindevicemanager.mm +++ b/src/multimedia/platform/darwin/qdarwindevicemanager.mm @@ -44,7 +44,9 @@ #include "private/qcoreaudiodeviceinfo_p.h" #include "private/qcoreaudioinput_p.h" #include "private/qcoreaudiooutput_p.h" +#include "private/avfcameracontrol_p.h" +#include <CoreVideo/CoreVideo.h> #import <AVFoundation/AVFoundation.h> #if defined(Q_OS_IOS) || defined(Q_OS_TVOS) @@ -180,6 +182,8 @@ QDarwinDeviceManager::QDarwinDeviceManager() #else // ### This should use the audio session manager #endif + updateCameraDevices(); + updateAudioDevices(); } @@ -233,6 +237,7 @@ void QDarwinDeviceManager::updateCameraDevices() AVCaptureDevice *defaultDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; + for (AVCaptureDevice *device in videoDevices) { QCameraInfoPrivate *info = new QCameraInfoPrivate; @@ -241,8 +246,55 @@ void QDarwinDeviceManager::updateCameraDevices() info->id = QByteArray([[device uniqueID] UTF8String]); info->description = QString::fromNSString([device localizedName]); +// qDebug() << "Camera:" << info->description; + + QSet<QSize> photoResolutions; + QList<QCameraFormat> videoFormats; + + for (AVCaptureDeviceFormat *format in device.formats) { + if (![format.mediaType isEqualTo:AVMediaTypeVideo]) + continue; + + auto dimensions = CMVideoFormatDescriptionGetDimensions(format.formatDescription); + QSize resolution(dimensions.width, dimensions.height); + photoResolutions.insert(resolution); +// qDebug() << " Format:" << resolution; + float maxFrameRate = 0; + float minFrameRate = 1.e6; + + auto encoding = CMVideoFormatDescriptionGetCodecType(format.formatDescription); + auto pixelFormat = AVFCameraControl::QtPixelFormatFromCVFormat(encoding); + // Ignore pixel formats we can't handle + if (pixelFormat == QVideoFrame::Format_Invalid) + continue; + + for (AVFrameRateRange *frameRateRange in format.videoSupportedFrameRateRanges) { + if (frameRateRange.minFrameRate < minFrameRate) + minFrameRate = frameRateRange.minFrameRate; + if (frameRateRange.maxFrameRate > maxFrameRate) + maxFrameRate = frameRateRange.maxFrameRate; + } +// qDebug() << " " << frameRateRange.minFrameRate << frameRateRange.maxFrameRate; + +#ifdef Q_OS_IOS + // ### +// CMVideoDimensions photoDim = format.highResolutionStillImageDimensions; +// QSize photoSize(photoDim.....) + // Add to photoresolutions +#endif + + auto *f = new QCameraFormatPrivate{ + QSharedData(), + pixelFormat, + resolution, + minFrameRate, + maxFrameRate + }; + videoFormats << f->create(); + } + info->videoFormats = videoFormats; - cameras.append(QCameraInfo(info)); + cameras.append(info->create()); } if (cameras != m_cameraDevices) { diff --git a/src/multimedia/platform/gstreamer/common/qgstutils.cpp b/src/multimedia/platform/gstreamer/common/qgstutils.cpp index 7903b48fe..49eec32b0 100644 --- a/src/multimedia/platform/gstreamer/common/qgstutils.cpp +++ b/src/multimedia/platform/gstreamer/common/qgstutils.cpp @@ -898,26 +898,55 @@ QSize QGstUtils::structurePixelAspectRatio(const GstStructure *s) return ratio; } -QPair<qreal, qreal> QGstUtils::structureFrameRateRange(const GstStructure *s) +QPair<float, float> QGstUtils::structureFrameRateRange(const GstStructure *s) { - QPair<qreal, qreal> rate; + float minRate = 0.; + float maxRate = 0.; if (!s) - return rate; - - int n, d; - if (gst_structure_get_fraction(s, "framerate", &n, &d)) { - rate.second = qreal(n) / d; - rate.first = rate.second; - } else if (gst_structure_get_fraction(s, "max-framerate", &n, &d)) { - rate.second = qreal(n) / d; - if (gst_structure_get_fraction(s, "min-framerate", &n, &d)) - rate.first = qreal(n) / d; - else - rate.first = qreal(1); + return {0.f, 0.f}; + + auto extractFraction = [] (const GValue *v) -> float { + return (float)gst_value_get_fraction_numerator(v)/(float)gst_value_get_fraction_denominator(v); + }; + auto extractFrameRate = [&] (const GValue *v) { + auto insert = [&] (float min, float max) { + if (max > maxRate) + maxRate = max; + if (min < minRate) + minRate = min; + }; + + if (GST_VALUE_HOLDS_FRACTION(v)) { + float rate = extractFraction(v); + insert(rate, rate); + } else if (GST_VALUE_HOLDS_FRACTION_RANGE(v)) { + auto *min = gst_value_get_fraction_range_max(v); + auto *max = gst_value_get_fraction_range_max(v); + insert(extractFraction(min), extractFraction(max)); + } + }; + + const GValue *gstFrameRates = gst_structure_get_value(s, "framerate"); + if (gstFrameRates) { + if (GST_VALUE_HOLDS_LIST(gstFrameRates)) { + guint nFrameRates = gst_value_list_get_size(gstFrameRates); + for (guint f = 0; f < nFrameRates; ++f) { + extractFrameRate(gst_value_list_get_value(gstFrameRates, f)); + } + } else { + extractFrameRate(gstFrameRates); + } + } else { + const GValue *min = gst_structure_get_value(s, "min-framerate"); + const GValue *max = gst_structure_get_value(s, "max-framerate"); + if (min && max) { + minRate = extractFraction(min); + maxRate = extractFraction(max); + } } - return rate; + return {minRate, maxRate}; } typedef QMap<QString, QString> FileExtensionMap; diff --git a/src/multimedia/platform/gstreamer/common/qgstutils_p.h b/src/multimedia/platform/gstreamer/common/qgstutils_p.h index 796721589..8a95d0d5e 100644 --- a/src/multimedia/platform/gstreamer/common/qgstutils_p.h +++ b/src/multimedia/platform/gstreamer/common/qgstutils_p.h @@ -77,7 +77,7 @@ namespace QGstUtils { QString name; QString description; int orientation; - QCamera::Position position; + QCameraInfo::Position position; QByteArray driver; }; @@ -115,7 +115,7 @@ namespace QGstUtils { Q_MULTIMEDIA_EXPORT QSize structureResolution(const GstStructure *s); Q_MULTIMEDIA_EXPORT QVideoFrame::PixelFormat structurePixelFormat(const GstStructure *s); Q_MULTIMEDIA_EXPORT QSize structurePixelAspectRatio(const GstStructure *s); - Q_MULTIMEDIA_EXPORT QPair<qreal, qreal> structureFrameRateRange(const GstStructure *s); + Q_MULTIMEDIA_EXPORT QPair<float, float> structureFrameRateRange(const GstStructure *s); Q_MULTIMEDIA_EXPORT QString fileExtensionForMimeType(const QString &mimeType); diff --git a/src/multimedia/platform/gstreamer/qgstreamerdevicemanager.cpp b/src/multimedia/platform/gstreamer/qgstreamerdevicemanager.cpp index df779a96c..db175075c 100644 --- a/src/multimedia/platform/gstreamer/qgstreamerdevicemanager.cpp +++ b/src/multimedia/platform/gstreamer/qgstreamerdevicemanager.cpp @@ -153,10 +153,40 @@ QList<QCameraInfo> QGstreamerDeviceManager::videoInputs() const gst_structure_get_boolean(properties, "is-default", &def); info->isDefault = def; if (def) - devices.prepend(QCameraInfo(info)); + devices.prepend(info->create()); else - devices.append(QCameraInfo(info)); + devices.append(info->create()); gst_structure_free(properties); + auto *caps = gst_device_get_caps(d); + if (caps) { + QList<QCameraFormat> formats; + QSet<QSize> photoResolutions; + + int size = gst_caps_get_size(caps); + for (int i = 0; i < size; ++i) { + auto *cap = gst_caps_get_structure(caps, i); + + QSize resolution = QGstUtils::structureResolution(cap); + if (!resolution.isValid()) + continue; + + auto pixelFormat = QGstUtils::structurePixelFormat(cap); + auto frameRate = QGstUtils::structureFrameRateRange(cap); + + auto *f = new QCameraFormatPrivate{ + QSharedData(), + pixelFormat, + resolution, + frameRate.first, + frameRate.second + }; + formats << f->create(); + photoResolutions.insert(resolution); + } + info->videoFormats = formats; + // ### sort resolutions? + info->photoResolutions = photoResolutions.values(); + } } } return devices; diff --git a/src/multimedia/platform/qnx/qqnxdevicemanager.cpp b/src/multimedia/platform/qnx/qqnxdevicemanager.cpp index 6b0d00dc9..d4c34d3d6 100644 --- a/src/multimedia/platform/qnx/qqnxdevicemanager.cpp +++ b/src/multimedia/platform/qnx/qqnxdevicemanager.cpp @@ -67,24 +67,24 @@ static QList<QCameraInfo> enumerateCameras() case CAMERA_UNIT_FRONT: p->id = BbCameraSession::cameraIdentifierFront(); p->description = tr("Front Camera"); - p->position = QCamera::FrontFace; + p->position = QCameraInfo::FrontFace; break; case CAMERA_UNIT_REAR: p->id = BbCameraSession::cameraIdentifierRear(); p->description = tr("Rear Camera"); - p->position = QCamera::BackFace; + p->position = QCameraInfo::BackFace; break; case CAMERA_UNIT_DESKTOP: p->id = devices->append(BbCameraSession::cameraIdentifierDesktop(); p->description = tr("Desktop Camera"); - p->position = QCamera::UnspecifiedPosition; + p->position = QCameraInfo::UnspecifiedPosition; break; default: break; } if (i == 0) p->isDefault = true; - cameras.append(QCameraInfo(p)); + cameras.append(p->create()); } return cameras; } diff --git a/src/multimedia/qmediadevicemanager.cpp b/src/multimedia/qmediadevicemanager.cpp index c83015c79..4873d1cd7 100644 --- a/src/multimedia/qmediadevicemanager.cpp +++ b/src/multimedia/qmediadevicemanager.cpp @@ -112,7 +112,7 @@ QList<QAudioDeviceInfo> QMediaDeviceManager::audioOutputs() /*! Returns a list of available cameras on the system which are located at \a position. - If \a position is not specified or if the value is QCamera::UnspecifiedPosition, a list of + If \a position is not specified or if the value is QCameraInfo::UnspecifiedPosition, a list of all available cameras will be returned. */ QList<QCameraInfo> QMediaDeviceManager::videoInputs() diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp index a64a9e157..2aae59509 100644 --- a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp +++ b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp @@ -44,6 +44,7 @@ #include <private/qvideooutputorientationhandler_p.h> #include <QtMultimedia/qmediasource.h> #include <QtMultimedia/qmediaservice.h> +#include <QtMultimedia/qcamera.h> #include <private/qfactoryloader_p.h> #include <QtCore/qloggingcategory.h> @@ -321,7 +322,7 @@ void QDeclarativeVideoOutput::_q_updateCameraInfo() if (m_mediaSource) { const QCamera *camera = qobject_cast<const QCamera *>(m_mediaSource); if (camera) { - QCameraInfo info(*camera); + QCameraInfo info = camera->cameraInfo(); if (m_cameraInfo != info) { m_cameraInfo = info; @@ -433,20 +434,6 @@ void QDeclarativeVideoOutput::_q_updateGeometry() void QDeclarativeVideoOutput::_q_screenOrientationChanged(int orientation) { - // If the source is a camera, take into account its sensor position and orientation - if (!m_cameraInfo.isNull()) { - switch (m_cameraInfo.position()) { - case QCamera::FrontFace: - // Front facing cameras are flipped horizontally, compensate the mirror - orientation += (360 - m_cameraInfo.orientation()); - break; - case QCamera::BackFace: - default: - orientation += m_cameraInfo.orientation(); - break; - } - } - setOrientation(orientation % 360); } diff --git a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp index ce5b8e507..9b6bf700f 100644 --- a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp +++ b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp @@ -106,7 +106,6 @@ void tst_QCameraBackend::testCameraInfo() for (const QCameraInfo &info : cameras) { QVERIFY(!info.id().isEmpty()); QVERIFY(!info.description().isEmpty()); - QVERIFY(info.orientation() % 90 == 0); } } @@ -119,19 +118,19 @@ void tst_QCameraBackend::testCtorWithCameraInfo() QCameraInfo info = QMediaDeviceManager::defaultVideoInput(); QCamera camera(info); QCOMPARE(camera.error(), QCamera::NoError); - QCOMPARE(QCameraInfo(camera), info); + QCOMPARE(camera.cameraInfo(), info); } { QCameraInfo info = QMediaDeviceManager::videoInputs().first(); QCamera camera(info); QCOMPARE(camera.error(), QCamera::NoError); - QCOMPARE(QCameraInfo(camera), info); + QCOMPARE(camera.cameraInfo(), info); } { // loading an invalid CameraInfo should fail QCamera *camera = new QCamera(QCameraInfo()); QCOMPARE(camera->error(), QCamera::CameraError); - QVERIFY(QCameraInfo(*camera).isNull()); + QVERIFY(camera->cameraInfo().isNull()); delete camera; } } @@ -139,17 +138,17 @@ void tst_QCameraBackend::testCtorWithCameraInfo() void tst_QCameraBackend::testCtorWithPosition() { { - QCamera camera(QCamera::UnspecifiedPosition); + QCamera camera(QCameraInfo::UnspecifiedPosition); QCOMPARE(camera.error(), QCamera::NoError); } { - QCamera camera(QCamera::FrontFace); + QCamera camera(QCameraInfo::FrontFace); // even if no camera is available at this position, it should not fail // and load the default camera QCOMPARE(camera.error(), QCamera::NoError); } { - QCamera camera(QCamera::BackFace); + QCamera camera(QCameraInfo::BackFace); // even if no camera is available at this position, it should not fail // and load the default camera QCOMPARE(camera.error(), QCamera::NoError); diff --git a/tests/auto/unit/multimedia/qcamera/tst_qcamera.cpp b/tests/auto/unit/multimedia/qcamera/tst_qcamera.cpp index 48e71a5e2..4d064b0e6 100644 --- a/tests/auto/unit/multimedia/qcamera/tst_qcamera.cpp +++ b/tests/auto/unit/multimedia/qcamera/tst_qcamera.cpp @@ -1606,8 +1606,8 @@ void tst_QCamera::testEnumDebug() qDebug() << QCamera::NoLock; QTest::ignoreMessage(QtDebugMsg, "QCamera::LockExposure"); qDebug() << QCamera::LockExposure; - QTest::ignoreMessage(QtDebugMsg, "QCamera::FrontFace "); - qDebug() << QCamera::FrontFace; + QTest::ignoreMessage(QtDebugMsg, "QCameraInfo::FrontFace "); + qDebug() << QCameraInfo::FrontFace; } void tst_QCamera::testCameraControl() @@ -1622,9 +1622,9 @@ void tst_QCamera::testConstructor() QCameraInfo defaultCamera = QMediaDeviceManager::defaultVideoInput(); QCameraInfo frontCamera, backCamera; for (const auto &c : cameras) { - if (frontCamera.isNull() && c.position() == QCamera::FrontFace) + if (frontCamera.isNull() && c.position() == QCameraInfo::FrontFace) frontCamera = c; - if (backCamera.isNull() && c.position() == QCamera::BackFace) + if (backCamera.isNull() && c.position() == QCameraInfo::BackFace) backCamera = c; } QVERIFY(!defaultCamera.isNull()); @@ -1639,7 +1639,7 @@ void tst_QCamera::testConstructor() } { - QCamera camera(QCamera::FrontFace); + QCamera camera(QCameraInfo::FrontFace); QCOMPARE(camera.availability(), QMultimedia::Available); QCOMPARE(camera.error(), QCamera::NoError); QCOMPARE(camera.cameraInfo(), frontCamera); @@ -1657,11 +1657,11 @@ void tst_QCamera::testConstructor() QCamera camera(cameraInfo); QCOMPARE(camera.availability(), QMultimedia::Available); QCOMPARE(camera.error(), QCamera::NoError); - QCOMPARE(QCameraInfo(camera), cameraInfo); + QCOMPARE(camera.cameraInfo(), cameraInfo); } { - QCamera camera(QCamera::BackFace); + QCamera camera(QCameraInfo::BackFace); QCOMPARE(camera.availability(), QMultimedia::Available); QCOMPARE(camera.error(), QCamera::NoError); QCOMPARE(camera.cameraInfo(), backCamera); @@ -1669,7 +1669,7 @@ void tst_QCamera::testConstructor() { // Should load the default camera when UnspecifiedPosition is requested - QCamera camera(QCamera::UnspecifiedPosition); + QCamera camera(QCameraInfo::UnspecifiedPosition); QCOMPARE(camera.availability(), QMultimedia::Available); QCOMPARE(camera.error(), QCamera::NoError); QCOMPARE(camera.cameraInfo(), defaultCamera); diff --git a/tests/auto/unit/multimedia/qcamerainfo/tst_qcamerainfo.cpp b/tests/auto/unit/multimedia/qcamerainfo/tst_qcamerainfo.cpp index 42deae79b..53f86c095 100644 --- a/tests/auto/unit/multimedia/qcamerainfo/tst_qcamerainfo.cpp +++ b/tests/auto/unit/multimedia/qcamerainfo/tst_qcamerainfo.cpp @@ -77,37 +77,33 @@ void tst_QCameraInfo::constructor() { // default camera QCamera camera; - QCameraInfo info(camera); + QCameraInfo info(camera.cameraInfo()); QVERIFY(!info.isNull()); QCOMPARE(info.id(), QStringLiteral("othercamera")); QCOMPARE(info.description(), QStringLiteral("othercamera desc")); - QCOMPARE(info.position(), QCamera::UnspecifiedPosition); - QCOMPARE(info.orientation(), 0); + QCOMPARE(info.position(), QCameraInfo::UnspecifiedPosition); } auto cameras = QMediaDeviceManager::videoInputs(); QCameraInfo info; for (const auto &c : cameras) { - if (c.position() == QCamera::BackFace) + if (c.position() == QCameraInfo::BackFace) info = c; } QVERIFY(!info.isNull()); QCamera camera(info); QCOMPARE(info, camera.cameraInfo()); - QCOMPARE(info, QCameraInfo(camera)); QVERIFY(!info.isNull()); QCOMPARE(info.id(), QStringLiteral("backcamera")); QCOMPARE(info.description(), QStringLiteral("backcamera desc")); - QCOMPARE(info.position(), QCamera::BackFace); - QCOMPARE(info.orientation(), 90); + QCOMPARE(info.position(), QCameraInfo::BackFace); QCameraInfo info2(info); QVERIFY(!info2.isNull()); QCOMPARE(info2.id(), QStringLiteral("backcamera")); QCOMPARE(info2.description(), QStringLiteral("backcamera desc")); - QCOMPARE(info2.position(), QCamera::BackFace); - QCOMPARE(info2.orientation(), 90); + QCOMPARE(info2.position(), QCameraInfo::BackFace); } void tst_QCameraInfo::defaultCamera() @@ -117,11 +113,10 @@ void tst_QCameraInfo::defaultCamera() QVERIFY(!info.isNull()); QCOMPARE(info.id(), QStringLiteral("othercamera")); QCOMPARE(info.description(), QStringLiteral("othercamera desc")); - QCOMPARE(info.position(), QCamera::UnspecifiedPosition); - QCOMPARE(info.orientation(), 0); + QCOMPARE(info.position(), QCameraInfo::UnspecifiedPosition); QCamera camera(info); - QCOMPARE(QCameraInfo(camera), info); + QCOMPARE(camera.cameraInfo(), info); } void tst_QCameraInfo::availableCameras() @@ -133,26 +128,24 @@ void tst_QCameraInfo::availableCameras() QVERIFY(!info.isNull()); QCOMPARE(info.id(), QStringLiteral("backcamera")); QCOMPARE(info.description(), QStringLiteral("backcamera desc")); - QCOMPARE(info.position(), QCamera::BackFace); - QCOMPARE(info.orientation(), 90); + QCOMPARE(info.position(), QCameraInfo::BackFace); info = cameras.at(1); QVERIFY(!info.isNull()); QCOMPARE(info.id(), QStringLiteral("othercamera")); QCOMPARE(info.description(), QStringLiteral("othercamera desc")); - QCOMPARE(info.position(), QCamera::UnspecifiedPosition); - QCOMPARE(info.orientation(), 0); + QCOMPARE(info.position(), QCameraInfo::UnspecifiedPosition); -// cameras = QMediaDeviceManager::videoInputs(QCamera::BackFace); +// cameras = QMediaDeviceManager::videoInputs(QCameraInfo::BackFace); // QCOMPARE(cameras.count(), 1); // info = cameras.at(0); // QVERIFY(!info.isNull()); // QCOMPARE(info.id(), QStringLiteral("backcamera")); // QCOMPARE(info.description(), QStringLiteral("backcamera desc")); -// QCOMPARE(info.position(), QCamera::BackFace); +// QCOMPARE(info.position(), QCameraInfo::BackFace); // QCOMPARE(info.orientation(), 90); -// cameras = QMediaDeviceManager::videoInputs(QCamera::FrontFace); +// cameras = QMediaDeviceManager::videoInputs(QCameraInfo::FrontFace); // QCOMPARE(cameras.count(), 0); } @@ -167,13 +160,13 @@ void tst_QCameraInfo::equality_operators() { QCamera camera(defaultCamera); - QVERIFY(QCameraInfo(camera) == defaultCamera); - QVERIFY(QCameraInfo(camera) == cameras.at(1)); + QVERIFY(camera.cameraInfo() == defaultCamera); + QVERIFY(camera.cameraInfo() == cameras.at(1)); } { QCamera camera(cameras.at(0)); - QVERIFY(QCameraInfo(camera) == cameras.at(0)); + QVERIFY(camera.cameraInfo() == cameras.at(0)); } } |