summaryrefslogtreecommitdiffstats
path: root/src/multimedia
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-09-07 13:41:00 +0200
committerAssam Boudjelthia <assam.boudjelthia@qt.io>2021-09-08 15:09:11 +0300
commit18c1261976d7838814468cb1cc31a3858cf363cd (patch)
tree84c8d4e6d64677b007e4d632883971c5f4c976a3 /src/multimedia
parente0f94543ff5b9310bfb735110949e66663179a34 (diff)
Fix orientation of camera frames on Android
Properly adjust orientation of video frames coming from the camera. Now we show the video of both cameras the right way in all orientations. When in portrait mode, swap the width and height of the video frames we create, to get the correct aspect ratio of the camera device. Pick-to: 6.2 6.2.0 Change-Id: I7168c672867988c419f160c817a380624392744e Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
Diffstat (limited to 'src/multimedia')
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp69
-rw-r--r--src/multimedia/platform/android/mediacapture/qandroidcamerasession_p.h2
-rw-r--r--src/multimedia/platform/android/wrappers/jni/androidcamera.cpp2
3 files changed, 57 insertions, 16 deletions
diff --git a/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp b/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp
index bb7083d40..1d85acf95 100644
--- a/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp
+++ b/src/multimedia/platform/android/mediacapture/qandroidcamerasession.cpp
@@ -48,6 +48,7 @@
#include <QtConcurrent/qtconcurrentrun.h>
#include <qfile.h>
#include <qguiapplication.h>
+#include <qscreen.h>
#include <qdebug.h>
#include <qvideoframe.h>
#include <private/qplatformimagecapture_p.h>
@@ -63,7 +64,6 @@ QAndroidCameraSession::QAndroidCameraSession(QObject *parent)
: QObject(parent)
, m_selectedCamera(0)
, m_camera(0)
- , m_nativeOrientation(0)
, m_videoOutput(0)
, m_savedState(-1)
, m_previewStarted(false)
@@ -76,6 +76,11 @@ QAndroidCameraSession::QAndroidCameraSession(QObject *parent)
if (qApp) {
connect(qApp, &QGuiApplication::applicationStateChanged,
this, &QAndroidCameraSession::onApplicationStateChanged);
+
+ auto screen = qApp->primaryScreen();
+ if (screen)
+ connect(screen, &QScreen::orientationChanged,
+ this, &QAndroidCameraSession::updateOrientation);
}
}
@@ -177,8 +182,6 @@ bool QAndroidCameraSession::open()
connect(m_camera, &AndroidCamera::takePictureFailed,
this, &QAndroidCameraSession::onCameraTakePictureFailed);
- m_nativeOrientation = m_camera->getNativeOrientation();
-
if (m_camera->getPreviewFormat() != AndroidCamera::NV21)
m_camera->setPreviewFormat(AndroidCamera::NV21);
@@ -314,8 +317,14 @@ void QAndroidCameraSession::applyResolution(const QSize &captureSize, bool resta
|| currentFpsRange.min != adjustedFps.min
|| currentFpsRange.max != adjustedFps.max) {
- if (m_videoOutput)
- m_videoOutput->setVideoSize(adjustedViewfinderResolution);
+ if (m_videoOutput) {
+ // fix the resolution of output based on the orientation
+ QSize outputResolution = adjustedViewfinderResolution;
+ const int rotation = currentCameraRotation();
+ if (rotation == 90 || rotation == 270)
+ outputResolution.transpose();
+ m_videoOutput->setVideoSize(outputResolution);
+ }
// if preview is started, we have to stop it first before changing its size
if (m_previewStarted && restartPreview)
@@ -384,8 +393,7 @@ bool QAndroidCameraSession::startPreview()
AndroidMultimediaUtils::enableOrientationListener(true);
- // Use the default native orientation as the orientation for the preview
- m_camera->setDisplayOrientation(m_nativeOrientation);
+ updateOrientation();
m_camera->startPreview();
m_previewStarted = true;
@@ -425,19 +433,52 @@ void QAndroidCameraSession::setImageSettings(const QImageEncoderSettings &settin
applyResolution(m_actualImageSettings.resolution());
}
+void QAndroidCameraSession::updateOrientation()
+{
+ if (!m_camera)
+ return;
+
+ m_camera->setDisplayOrientation(currentCameraRotation());
+ applyResolution(m_actualImageSettings.resolution());
+}
+
+
int QAndroidCameraSession::currentCameraRotation() const
{
if (!m_camera)
return 0;
- // subtract natural camera orientation and physical device orientation
- int rotation = 0;
- int deviceOrientation = (AndroidMultimediaUtils::getDeviceOrientation() + 45) / 90 * 90;
- if (m_camera->getFacing() == AndroidCamera::CameraFacingFront)
- rotation = (m_nativeOrientation - deviceOrientation + 360) % 360;
- else // back-facing camera
- rotation = (m_nativeOrientation + deviceOrientation) % 360;
+ auto screen = QGuiApplication::primaryScreen();
+ auto screenOrientation = screen->orientation();
+ if (screenOrientation == Qt::PrimaryOrientation)
+ screenOrientation = screen->primaryOrientation();
+ int deviceOrientation = 0;
+ switch (screenOrientation) {
+ case Qt::PrimaryOrientation:
+ case Qt::PortraitOrientation:
+ break;
+ case Qt::LandscapeOrientation:
+ deviceOrientation = 90;
+ break;
+ case Qt::InvertedPortraitOrientation:
+ deviceOrientation = 180;
+ break;
+ case Qt::InvertedLandscapeOrientation:
+ deviceOrientation = 270;
+ break;
+ }
+
+ int nativeCameraOrientation = m_camera->getNativeOrientation();
+
+ int rotation;
+ // subtract natural camera orientation and physical device orientation
+ if (m_camera->getFacing() == AndroidCamera::CameraFacingFront) {
+ rotation = (nativeCameraOrientation + deviceOrientation) % 360;
+ rotation = (360 - rotation) % 360; // compensate the mirror
+ } else { // back-facing camera
+ rotation = (nativeCameraOrientation - deviceOrientation + 360) % 360;
+ }
return rotation;
}
diff --git a/src/multimedia/platform/android/mediacapture/qandroidcamerasession_p.h b/src/multimedia/platform/android/mediacapture/qandroidcamerasession_p.h
index 83228b692..56674757d 100644
--- a/src/multimedia/platform/android/mediacapture/qandroidcamerasession_p.h
+++ b/src/multimedia/platform/android/mediacapture/qandroidcamerasession_p.h
@@ -127,6 +127,7 @@ Q_SIGNALS:
private Q_SLOTS:
void onVideoOutputReady(bool ready);
+ void updateOrientation();
void onApplicationStateChanged(Qt::ApplicationState state);
@@ -161,7 +162,6 @@ private:
int m_selectedCamera;
AndroidCamera *m_camera;
- int m_nativeOrientation;
QAndroidVideoOutput *m_videoOutput;
bool m_active = false;
diff --git a/src/multimedia/platform/android/wrappers/jni/androidcamera.cpp b/src/multimedia/platform/android/wrappers/jni/androidcamera.cpp
index 2ee3512f0..e40921f38 100644
--- a/src/multimedia/platform/android/wrappers/jni/androidcamera.cpp
+++ b/src/multimedia/platform/android/wrappers/jni/androidcamera.cpp
@@ -1348,7 +1348,7 @@ void AndroidCameraPrivate::setFocusAreas(const QList<QRect> &areas)
{
const std::lock_guard<QRecursiveMutex> locker(m_parametersMutex);
- if (!m_parameters.isValid())
+ if (!m_parameters.isValid() || areas.isEmpty())
return;
QJniObject list;