diff options
Diffstat (limited to 'src')
4 files changed, 50 insertions, 6 deletions
diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp index 3a50139c3..5ff19d1c1 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.cpp @@ -92,6 +92,7 @@ QAndroidCameraSession::QAndroidCameraSession(QObject *parent) , m_selectedCamera(0) , m_camera(0) , m_nativeOrientation(0) + , m_previewOrientation(0) , m_videoOutput(0) , m_captureMode(QCamera::CaptureViewfinder) , m_state(QCamera::UnloadedState) @@ -183,10 +184,20 @@ bool QAndroidCameraSession::open() connect(m_camera, SIGNAL(pictureExposed()), this, SLOT(onCameraPictureExposed())); connect(m_camera, SIGNAL(pictureCaptured(QByteArray)), this, SLOT(onCameraPictureCaptured(QByteArray))); connect(m_camera, SIGNAL(previewFrameAvailable(QByteArray)), this, SLOT(onCameraPreviewFrameAvailable(QByteArray))); + m_nativeOrientation = m_camera->getNativeOrientation(); + + // Preview orientation will always match the device natural orientation + if (m_camera->getFacing() == JCamera::CameraFacingFront) + m_previewOrientation = 360 - m_nativeOrientation; + else + m_previewOrientation = m_nativeOrientation; + m_status = QCamera::LoadedStatus; + if (m_camera->getPreviewFormat() != JCamera::NV21) m_camera->setPreviewFormat(JCamera::NV21); + emit opened(); } else { m_status = QCamera::UnavailableStatus; @@ -257,8 +268,16 @@ void QAndroidCameraSession::adjustViewfinderSize(const QSize &captureSize, bool } if (m_camera->previewSize() != viewfinderResolution) { - if (m_videoOutput) - m_videoOutput->setVideoSize(viewfinderResolution); + if (m_videoOutput) { + QSize size = viewfinderResolution; + + // If the preview orientation is not the defaut one (0 or 180 degrees), + // we have to invert the output aspect ratio. + if (m_previewOrientation % 180) + size.transpose(); + + m_videoOutput->setVideoSize(size); + } // if preview is started, we have to stop it first before changing its size if (m_previewStarted && restartPreview) @@ -282,6 +301,7 @@ void QAndroidCameraSession::startPreview() applyImageSettings(); adjustViewfinderSize(m_imageSettings.resolution()); + m_camera->setDisplayOrientation(m_previewOrientation); if (m_videoOutput && m_videoOutput->isReady()) onVideoOutputReady(true); @@ -558,10 +578,11 @@ void QAndroidCameraSession::onCameraPreviewFrameAvailable(const QByteArray &data QtConcurrent::run(this, &QAndroidCameraSession::processPreviewImage, m_currentImageCaptureId, - data); + data, + m_camera->getRotation()); } -void QAndroidCameraSession::processPreviewImage(int id, const QByteArray &data) +void QAndroidCameraSession::processPreviewImage(int id, const QByteArray &data, int rotation) { QSize frameSize = m_camera->previewSize(); QImage preview(frameSize, QImage::Format_ARGB32); @@ -570,11 +591,17 @@ void QAndroidCameraSession::processPreviewImage(int id, const QByteArray &data) frameSize.width(), frameSize.height()); + QTransform transform; + // Preview display of front-facing cameras is flipped horizontally, but the frame data // we get here is not. Flip it ourselves if the camera is front-facing to match what the user // sees on the viewfinder. if (m_camera->getFacing() == JCamera::CameraFacingFront) - preview = preview.transformed(QTransform().scale(-1, 1)); + transform.scale(-1, 1); + + transform.rotate(rotation); + + preview = preview.transformed(transform); emit imageCaptured(id, preview); } diff --git a/src/plugins/android/src/mediacapture/qandroidcamerasession.h b/src/plugins/android/src/mediacapture/qandroidcamerasession.h index 897cf52d1..17ea4171f 100644 --- a/src/plugins/android/src/mediacapture/qandroidcamerasession.h +++ b/src/plugins/android/src/mediacapture/qandroidcamerasession.h @@ -124,7 +124,7 @@ private: void stopPreview(); void applyImageSettings(); - void processPreviewImage(int id, const QByteArray &data); + void processPreviewImage(int id, const QByteArray &data, int rotation); void processCapturedImage(int id, const QByteArray &data, const QSize &resolution, @@ -134,6 +134,7 @@ private: int m_selectedCamera; JCamera *m_camera; int m_nativeOrientation; + int m_previewOrientation; QAndroidVideoOutput *m_videoOutput; QCamera::CaptureModes m_captureMode; diff --git a/src/plugins/android/src/wrappers/jcamera.cpp b/src/plugins/android/src/wrappers/jcamera.cpp index 2d42ffbd6..e69cb554d 100644 --- a/src/plugins/android/src/wrappers/jcamera.cpp +++ b/src/plugins/android/src/wrappers/jcamera.cpp @@ -118,6 +118,7 @@ JCamera::JCamera(int cameraId, jobject cam) : QObject() , QJNIObjectPrivate(cam) , m_cameraId(cameraId) + , m_rotation(0) , m_hasAPI14(false) { if (isValid()) { @@ -205,6 +206,11 @@ int JCamera::getNativeOrientation() return m_info.getField<jint>("orientation"); } +void JCamera::setDisplayOrientation(int degrees) +{ + callMethod<void>("setDisplayOrientation", "(I)V", degrees); +} + QSize JCamera::getPreferredPreviewSizeForVideo() { if (!m_parameters.isValid()) @@ -612,10 +618,16 @@ void JCamera::setRotation(int rotation) if (!m_parameters.isValid()) return; + m_rotation = rotation; m_parameters.callMethod<void>("setRotation", "(I)V", rotation); applyParameters(); } +int JCamera::getRotation() const +{ + return m_rotation; +} + QList<QSize> JCamera::getSupportedPictureSizes() { QList<QSize> list; diff --git a/src/plugins/android/src/wrappers/jcamera.h b/src/plugins/android/src/wrappers/jcamera.h index 464ca3cb2..7c47ec7a2 100644 --- a/src/plugins/android/src/wrappers/jcamera.h +++ b/src/plugins/android/src/wrappers/jcamera.h @@ -82,6 +82,8 @@ public: CameraFacing getFacing(); int getNativeOrientation(); + void setDisplayOrientation(int degrees); + QSize getPreferredPreviewSizeForVideo(); QList<QSize> getSupportedPreviewSizes(); @@ -136,6 +138,7 @@ public: void setWhiteBalance(const QString &value); void setRotation(int rotation); + int getRotation() const; QList<QSize> getSupportedPictureSizes(); void setPictureSize(const QSize &size); @@ -174,6 +177,7 @@ private: QJNIObjectPrivate m_parameters; QSize m_previewSize; + int m_rotation; bool m_hasAPI14; }; |