Android: fix setting the camera preview resolution.
authorYoann Lopes <yoann.lopes@theqtcompany.com>
Tue, 5 May 2015 14:40:05 +0000 (16:40 +0200)
committerYoann Lopes <yoann.lopes@theqtcompany.com>
Wed, 27 May 2015 12:18:43 +0000 (12:18 +0000)
- When the video capture resolution or the image capture resolution
  changes, we now always set the viewfinder resolution to the highest
  available one with the same aspect ratio as the capture resolution.
  We were previously not doing anything if the new capture resolution
  had the same aspect ratio as the current viewfinder resolution.
- Some devices don't support using a viewfinder resolution different
  from the video capture resolution. Make sure we handle this case.

Change-Id: I8d3ab7b01c56ed78d1ca838a522ba459692fc332
Reviewed-by: Christian Stromme <christian.stromme@theqtcompany.com>
src/plugins/android/src/mediacapture/qandroidcamerasession.cpp
src/plugins/android/src/mediacapture/qandroidcapturesession.cpp
src/plugins/android/src/mediacapture/qandroidcapturesession.h
src/plugins/android/src/wrappers/jni/androidcamera.cpp

index 2ff1759..4a64e1b 100644 (file)
@@ -277,26 +277,28 @@ void QAndroidCameraSession::adjustViewfinderSize(const QSize &captureSize, bool
         return;
 
     QSize currentViewfinderResolution = m_camera->previewSize();
-    const qreal aspectRatio = qreal(captureSize.width()) / qreal(captureSize.height());
-    if (currentViewfinderResolution.isValid() &&
-            qAbs(aspectRatio - (qreal(currentViewfinderResolution.width()) / currentViewfinderResolution.height())) < 0.01) {
-        return;
-    }
-
     QSize adjustedViewfinderResolution;
-    QList<QSize> previewSizes = m_camera->getSupportedPreviewSizes();
-    for (int i = previewSizes.count() - 1; i >= 0; --i) {
-        const QSize &size = previewSizes.at(i);
+
+    if (m_captureMode.testFlag(QCamera::CaptureVideo) && m_camera->getPreferredPreviewSizeForVideo().isEmpty()) {
+        // According to the Android doc, if getPreferredPreviewSizeForVideo() returns null, it means
+        // the preview size cannot be different from the capture size
+        adjustedViewfinderResolution = captureSize;
+    } else {
         // search for viewfinder resolution with the same aspect ratio
-        if (qAbs(aspectRatio - (qreal(size.width()) / size.height())) < 0.01) {
-            adjustedViewfinderResolution = size;
-            break;
+        const qreal aspectRatio = qreal(captureSize.width()) / qreal(captureSize.height());
+        QList<QSize> previewSizes = m_camera->getSupportedPreviewSizes();
+        for (int i = previewSizes.count() - 1; i >= 0; --i) {
+            const QSize &size = previewSizes.at(i);
+            if (qAbs(aspectRatio - (qreal(size.width()) / size.height())) < 0.01) {
+                adjustedViewfinderResolution = size;
+                break;
+            }
         }
-    }
 
-    if (!adjustedViewfinderResolution.isValid()) {
-        qWarning("Cannot find a viewfinder resolution matching the capture aspect ratio.");
-        return;
+        if (!adjustedViewfinderResolution.isValid()) {
+            qWarning("Cannot find a viewfinder resolution matching the capture aspect ratio.");
+            return;
+        }
     }
 
     if (currentViewfinderResolution != adjustedViewfinderResolution) {
index af80330..aaad8fd 100644 (file)
@@ -48,7 +48,6 @@ QAndroidCaptureSession::QAndroidCaptureSession(QAndroidCameraSession *cameraSess
     , m_duration(0)
     , m_state(QMediaRecorder::StoppedState)
     , m_status(QMediaRecorder::UnloadedStatus)
-    , m_resolutionDirty(false)
     , m_containerFormatDirty(true)
     , m_videoSettingsDirty(true)
     , m_audioSettingsDirty(true)
@@ -321,9 +320,6 @@ void QAndroidCaptureSession::setVideoSettings(const QVideoEncoderSettings &setti
     if (!m_cameraSession || m_videoSettings == settings)
         return;
 
-    if (m_videoSettings.resolution() != settings.resolution())
-        m_resolutionDirty = true;
-
     m_videoSettings = settings;
     m_videoSettingsDirty = true;
 }
@@ -376,7 +372,6 @@ void QAndroidCaptureSession::applySettings()
     if (m_cameraSession && m_cameraSession->camera() && m_videoSettingsDirty) {
         if (m_videoSettings.resolution().isEmpty()) {
             m_videoSettings.setResolution(m_defaultSettings.videoResolution);
-            m_resolutionDirty = true;
         } else if (!m_supportedResolutions.contains(m_videoSettings.resolution())) {
             // if the requested resolution is not supported, find the closest one
             QSize reqSize = m_videoSettings.resolution();
@@ -388,7 +383,6 @@ void QAndroidCaptureSession::applySettings()
             }
             int closestIndex = qt_findClosestValue(supportedPixelCounts, reqPixelCount);
             m_videoSettings.setResolution(m_supportedResolutions.at(closestIndex));
-            m_resolutionDirty = true;
         }
 
         if (m_videoSettings.frameRate() <= 0)
@@ -413,12 +407,8 @@ void QAndroidCaptureSession::applySettings()
 
 void QAndroidCaptureSession::updateViewfinder()
 {
-    if (!m_resolutionDirty)
-        return;
-
     m_cameraSession->camera()->stopPreview();
     m_cameraSession->adjustViewfinderSize(m_videoSettings.resolution(), false);
-    m_resolutionDirty = false;
 }
 
 void QAndroidCaptureSession::restartViewfinder()
index 90af39f..a0e7a89 100644 (file)
@@ -161,7 +161,6 @@ private:
     QString m_containerFormat;
     QAudioEncoderSettings m_audioSettings;
     QVideoEncoderSettings m_videoSettings;
-    bool m_resolutionDirty;
     bool m_containerFormatDirty;
     bool m_videoSettingsDirty;
     bool m_audioSettingsDirty;
index d9c8bef..7496e9c 100644 (file)
@@ -786,6 +786,9 @@ QSize AndroidCameraPrivate::getPreferredPreviewSizeForVideo()
     QJNIObjectPrivate size = m_parameters.callObjectMethod("getPreferredPreviewSizeForVideo",
                                                            "()Landroid/hardware/Camera$Size;");
 
+    if (!size.isValid())
+        return QSize();
+
     return QSize(size.getField<jint>("width"), size.getField<jint>("height"));
 }