Android: fix setting the camera preview resolution.

- 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>
This commit is contained in:
Yoann Lopes
2015-05-05 16:40:05 +02:00
parent 008d57e1d7
commit 83d1255080
4 changed files with 23 additions and 29 deletions

View 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);
// search for viewfinder resolution with the same aspect ratio
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 (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
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 (currentViewfinderResolution != adjustedViewfinderResolution) {

View 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()

View 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;

View 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"));
}