diff options
author | Lars Knoll <lars.knoll@qt.io> | 2021-09-08 16:07:06 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-09-09 18:33:15 +0000 |
commit | d18e2c0bfc02fb486516a8475fce9c7c4a6a91b9 (patch) | |
tree | 0dca5dc231d279ac2a4274fe457e238f11359d6a | |
parent | dbbf18376d0166877bb1395dee17e06e7b129e8b (diff) |
Fix camera orientation handling on iOS
Ensure the video frames coming from the camera are always upright
with regards to the devices orientation.
Change-Id: I30e816f0eaa2ee5c933ef1409fad77a43e4864ed
Reviewed-by: Doris Verria <doris.verria@qt.io>
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit d326872b43c9cbe3d6d12fb50391d734edb7690d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
4 files changed, 40 insertions, 2 deletions
diff --git a/src/multimedia/platform/darwin/camera/avfcamerarenderer.mm b/src/multimedia/platform/darwin/camera/avfcamerarenderer.mm index 002e95e3c..016ee3333 100644 --- a/src/multimedia/platform/darwin/camera/avfcamerarenderer.mm +++ b/src/multimedia/platform/darwin/camera/avfcamerarenderer.mm @@ -115,6 +115,8 @@ AVFCameraRenderer::AVFCameraRenderer(QObject *parent) : QObject(parent) { m_viewfinderFramesDelegate = [[AVFCaptureFramesDelegate alloc] initWithRenderer:this]; + connect(&m_orientationHandler, &QVideoOutputOrientationHandler::orientationChanged, + this, &AVFCameraRenderer::deviceOrientationChanged); } AVFCameraRenderer::~AVFCameraRenderer() @@ -137,6 +139,7 @@ void AVFCameraRenderer::reconfigure() if (m_layer) m_sink->setNativeSize(QSize(m_layer.bounds.size.width, m_layer.bounds.size.height)); nativeSizeChanged(); + deviceOrientationChanged(); } void AVFCameraRenderer::configureAVCaptureSession(AVFCameraSession *cameraSession) @@ -172,6 +175,38 @@ void AVFCameraRenderer::updateCaptureConnection() // If the connection does't support mirroring, we'll have to do it ourselves m_needsHorizontalMirroring = !connection.isVideoMirrored && m_cameraSession->videoCaptureDevice().position == AVCaptureDevicePositionFront; + + deviceOrientationChanged(); +} + +void AVFCameraRenderer::deviceOrientationChanged(int angle) +{ + AVCaptureConnection *connection = [m_videoDataOutput connectionWithMediaType:AVMediaTypeVideo]; + if (connection == nil || !m_cameraSession->videoCaptureDevice()) + return; + + if (!connection.supportsVideoOrientation) + return; + + if (angle < 0) + angle = m_orientationHandler.currentOrientation(); + + AVCaptureVideoOrientation orientation = AVCaptureVideoOrientationPortrait; + switch (angle) { + default: + break; + case 90: + orientation = AVCaptureVideoOrientationLandscapeRight; + break; + case 180: + // this keeps the last orientation, don't do anything + return; + case 270: + orientation = AVCaptureVideoOrientationLandscapeLeft; + break; + } + + connection.videoOrientation = orientation; } //can be called from non main thread diff --git a/src/multimedia/platform/darwin/camera/avfcamerarenderer_p.h b/src/multimedia/platform/darwin/camera/avfcamerarenderer_p.h index a622a9eaa..9455f593d 100644 --- a/src/multimedia/platform/darwin/camera/avfcamerarenderer_p.h +++ b/src/multimedia/platform/darwin/camera/avfcamerarenderer_p.h @@ -55,6 +55,7 @@ #include <QtMultimedia/qvideoframe.h> #include <QtCore/qmutex.h> #include <private/avfvideosink_p.h> +#include <private/qvideooutputorientationhandler_p.h> #include <CoreVideo/CVBase.h> #include <CoreVideo/CVPixelBuffer.h> @@ -101,6 +102,8 @@ Q_SIGNALS: private Q_SLOTS: void handleViewfinderFrame(); void updateCaptureConnection(); +public Q_SLOTS: + void deviceOrientationChanged(int angle = -1); private: AVFCaptureFramesDelegate *m_viewfinderFramesDelegate = nullptr; @@ -116,6 +119,7 @@ private: QVideoFrame m_lastViewfinderFrame; QMutex m_vfMutex; dispatch_queue_t m_delegateQueue; + QVideoOutputOrientationHandler m_orientationHandler; friend class CVImageVideoBuffer; }; diff --git a/src/multimedia/platform/darwin/camera/avfcamerasession.mm b/src/multimedia/platform/darwin/camera/avfcamerasession.mm index 467ff1c69..4a6d4ddeb 100644 --- a/src/multimedia/platform/darwin/camera/avfcamerasession.mm +++ b/src/multimedia/platform/darwin/camera/avfcamerasession.mm @@ -192,6 +192,7 @@ void AVFCameraSession::setActiveCamera(const QCameraDevice &info) this, &AVFCameraSession::newViewfinderFrame); updateVideoOutput(); } + m_videoOutput->deviceOrientationChanged(); [m_captureSession commitConfiguration]; diff --git a/src/multimedia/platform/darwin/camera/avfmediaencoder_p.h b/src/multimedia/platform/darwin/camera/avfmediaencoder_p.h index 8bb05926a..9e80c4c13 100644 --- a/src/multimedia/platform/darwin/camera/avfmediaencoder_p.h +++ b/src/multimedia/platform/darwin/camera/avfmediaencoder_p.h @@ -57,7 +57,6 @@ #include <private/qplatformmediaencoder_p.h> #include <private/qplatformmediacapture_p.h> -#include <private/qvideooutputorientationhandler_p.h> #include <QtMultimedia/qmediametadata.h> #include <QtCore/qglobal.h> @@ -125,7 +124,6 @@ private: NSDictionary *m_audioSettings; NSDictionary *m_videoSettings; - QVideoOutputOrientationHandler m_orientationHandler; }; QT_END_NAMESPACE |