Merge lp:~fboucault/qtubuntu-camera/resolution_fixes into lp:qtubuntu-camera

Proposed by Florian Boucault
Status: Superseded
Proposed branch: lp:~fboucault/qtubuntu-camera/resolution_fixes
Merge into: lp:qtubuntu-camera
Diff against target: 1161 lines (+302/-286)
28 files modified
.qmake.conf (+5/-0)
aalCamera.pro (+2/-0)
src/aalcameracontrol.cpp (+14/-5)
src/aalcamerafocuscontrol.cpp (+2/-0)
src/aalcameraservice.cpp (+43/-20)
src/aalcameraservice.h (+4/-1)
src/aalimagecapturecontrol.cpp (+0/-123)
src/aalimagecapturecontrol.h (+0/-10)
src/aalimageencodercontrol.cpp (+53/-30)
src/aalimageencodercontrol.h (+2/-2)
src/aalvideodeviceselectorcontrol.cpp (+3/-1)
src/aalvideoencodersettingscontrol.cpp (+11/-1)
src/aalvideorenderercontrol.cpp (+1/-4)
src/aalviewfindersettingscontrol.cpp (+7/-21)
src/aalviewfindersettingscontrol.h (+1/-1)
src/src.pro (+1/-9)
unittests/aalcameracontrol/aalcameraservice.cpp (+15/-0)
unittests/aalcameraexposurecontrol/aalcameraservice.cpp (+15/-0)
unittests/aalcameraflashcontrol/aalcameraservice.cpp (+15/-0)
unittests/aalcamerafocuscontrol/aalcameraservice.cpp (+15/-0)
unittests/aalcamerazoomcontrol/aalcameraservice.cpp (+15/-0)
unittests/aalimagecapturecontrol/aalcameraservice.cpp (+15/-0)
unittests/aalimagecapturecontrol/aalimageencodercontrol.cpp (+4/-8)
unittests/aalimagecapturecontrol/tst_aalimagecapturecontrol.cpp (+0/-44)
unittests/aalvideodeviceselectorcontrol/aalcameraservice.cpp (+15/-5)
unittests/aalvideodeviceselectorcontrol/aalimageencodercontrol.cpp (+2/-1)
unittests/aalviewfindersettingscontrol/aalcameraservice.cpp (+34/-0)
unittests/stubs/aalcameraservice_stub.cpp (+8/-0)
To merge this branch: bzr merge lp:~fboucault/qtubuntu-camera/resolution_fixes
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Ubuntu Phablet Team Pending
Review via email: mp+274404@code.launchpad.net

This proposal has been superseded by a proposal from 2015-11-25.

Commit message

Make it possible to set resolution at application startup by not
starting the viewfinder the first time the camera state is set to Unloaded.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
164. By Florian Boucault

Merged with staging

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '.qmake.conf'
2--- .qmake.conf 1970-01-01 00:00:00 +0000
3+++ .qmake.conf 2015-11-17 15:24:47 +0000
4@@ -0,0 +1,5 @@
5+PKG_CONFIG_ARCH = $$section(QMAKE_CC, -, 0, -2)
6+!isEmpty (PKG_CONFIG_ARCH) {
7+ PKG_CONFIG = $$PKG_CONFIG_ARCH-pkg-config
8+}
9+
10
11=== modified file 'aalCamera.pro'
12--- aalCamera.pro 2012-11-01 14:51:08 +0000
13+++ aalCamera.pro 2015-11-17 15:24:47 +0000
14@@ -5,3 +5,5 @@
15 SUBDIRS += \
16 src \
17 unittests
18+
19+OTHER_FILES += .qmake.conf
20
21=== modified file 'src/aalcameracontrol.cpp'
22--- src/aalcameracontrol.cpp 2013-07-26 16:46:16 +0000
23+++ src/aalcameracontrol.cpp 2015-11-17 15:24:47 +0000
24@@ -42,14 +42,25 @@
25 if (m_state == state)
26 return;
27
28- if (m_state == QCamera::ActiveState) {
29- m_service->disconnectCamera();
30- } else {
31+ if (state == QCamera::ActiveState) {
32 bool ok = m_service->connectCamera();
33 if (!ok) {
34 Q_EMIT error(QCamera::CameraError, QLatin1String("Unable to connect to camera"));
35 return;
36 }
37+ m_service->startPreview();
38+ } else if (state == QCamera::LoadedState) {
39+ if (m_state == QCamera::UnloadedState) {
40+ bool ok = m_service->connectCamera();
41+ if (!ok) {
42+ Q_EMIT error(QCamera::CameraError, QLatin1String("Unable to connect to camera"));
43+ return;
44+ }
45+ } else {
46+ m_service->disconnectCamera();
47+ }
48+ } else if (state == QCamera::UnloadedState) {
49+ m_service->disconnectCamera();
50 }
51
52 m_state = state;
53@@ -106,9 +117,7 @@
54
55 void AalCameraControl::handleError()
56 {
57- setState(QCamera::LoadedState);
58 Q_EMIT error(QCamera::CameraError, QLatin1String("Unknown error in camera"));
59- setState(QCamera::ActiveState);
60 }
61
62 void AalCameraControl::errorCB(void *context)
63
64=== modified file 'src/aalcamerafocuscontrol.cpp'
65--- src/aalcamerafocuscontrol.cpp 2015-04-09 17:54:55 +0000
66+++ src/aalcamerafocuscontrol.cpp 2015-11-17 15:24:47 +0000
67@@ -100,6 +100,7 @@
68 return;
69
70 m_focusRunning = false;
71+ m_service->updateCaptureReady();
72 AutoFocusMode focusMode = qt2Android(mode);
73 m_focusMode = mode;
74 if (m_service->androidControl()) {
75@@ -154,6 +155,7 @@
76 AutoFocusMode mode = qt2Android(m_focusMode);
77 android_camera_set_auto_focus_mode(control, mode);
78 m_focusRunning = false;
79+ m_service->updateCaptureReady();
80 }
81
82 void AalCameraFocusControl::startFocus()
83
84=== modified file 'src/aalcameraservice.cpp'
85--- src/aalcameraservice.cpp 2015-01-28 14:11:53 +0000
86+++ src/aalcameraservice.cpp 2015-11-17 15:24:47 +0000
87@@ -33,6 +33,7 @@
88 #include <hybris/camera/camera_compatibility_layer.h>
89
90 #include <QDebug>
91+#include <cmath>
92
93 AalCameraService *AalCameraService::m_service = 0;
94
95@@ -171,16 +172,13 @@
96
97 m_androidListener->context = m_androidControl;
98 initControls(m_androidControl, m_androidListener);
99- m_videoOutput->startPreview();
100
101 return true;
102 }
103
104 void AalCameraService::disconnectCamera()
105 {
106- if (m_service->videoOutputControl()) {
107- m_service->videoOutputControl()->stopPreview();
108- }
109+ stopPreview();
110
111 if (m_androidControl) {
112 android_camera_disconnect(m_androidControl);
113@@ -193,6 +191,20 @@
114 }
115 }
116
117+void AalCameraService::startPreview()
118+{
119+ if (m_videoOutput) {
120+ m_videoOutput->startPreview();
121+ }
122+}
123+
124+void AalCameraService::stopPreview()
125+{
126+ if (m_videoOutput) {
127+ m_videoOutput->stopPreview();
128+ }
129+}
130+
131 bool AalCameraService::isCameraActive() const
132 {
133 return m_cameraControl->state() == QCamera::ActiveState;
134@@ -211,7 +223,7 @@
135 m_imageEncoderControl->enablePhotoMode();
136 m_focusControl->enablePhotoMode();
137 m_zoomControl->enablePhotoMode();
138- m_viewfinderControl->setAspectRatio(m_imageCaptureControl->getAspectRatio());
139+ m_viewfinderControl->setAspectRatio(m_imageEncoderControl->getAspectRatio());
140 }
141
142 /*!
143@@ -225,15 +237,6 @@
144 }
145
146 /*!
147- * \brief AalCameraService::isReady return if the camera is ready for capturing
148- * \return
149- */
150-bool AalCameraService::isReady() const
151-{
152- return m_imageCaptureControl->isReadyForCapture();
153-}
154-
155-/*!
156 * \brief AalCameraService::isRecording returns true is a video recording is
157 * currently ongoing
158 * \return
159@@ -268,17 +271,37 @@
160 void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener)
161 {
162 m_cameraControl->init(camControl, listener);
163+ m_videoOutput->init(camControl, listener);
164+ m_viewfinderControl->init(camControl, listener);
165 m_imageEncoderControl->init(camControl);
166 m_imageCaptureControl->init(camControl, listener);
167 m_flashControl->init(camControl);
168 m_focusControl->init(camControl, listener);
169 m_zoomControl->init(camControl, listener);
170 m_videoEncoderControl->init(camControl, listener);
171- if (m_cameraControl->captureMode() == QCamera::CaptureStillImage)
172- m_viewfinderControl->setAspectRatio(m_imageCaptureControl->getAspectRatio());
173- else
174- m_viewfinderControl->setAspectRatio(m_videoEncoderControl->getAspectRatio());
175- m_viewfinderControl->init(camControl, listener);
176- m_videoOutput->init(camControl, listener);
177 m_exposureControl->init(camControl, listener);
178 }
179+
180+QSize AalCameraService::selectSizeWithAspectRatio(const QList<QSize> &sizes, float targetAspectRatio) const
181+{
182+ QSize selectedSize;
183+ long selectedPixelCount = 0;
184+ const float EPSILON = 0.02;
185+
186+ if (!sizes.empty()) {
187+ // Loop over all sizes until we find the highest one that matches targetAspectRatio.
188+ QList<QSize>::const_iterator it = sizes.begin();
189+ while (it != sizes.end()) {
190+ QSize size = *it;
191+ const float aspectRatio = (float)size.width() / (float)size.height();
192+ const long pixelCount = (long)size.width() * (long)size.height();
193+ if (fabs(aspectRatio - targetAspectRatio) < EPSILON && pixelCount > selectedPixelCount) {
194+ selectedSize = size;
195+ selectedPixelCount = pixelCount;
196+ }
197+ ++it;
198+ }
199+ }
200+
201+ return selectedSize;
202+}
203
204=== modified file 'src/aalcameraservice.h'
205--- src/aalcameraservice.h 2014-07-30 19:35:51 +0000
206+++ src/aalcameraservice.h 2015-11-17 15:24:47 +0000
207@@ -18,6 +18,7 @@
208 #define AALCAMERASERVICE_H
209
210 #include <QMediaService>
211+#include <QSize>
212
213 class AalCameraControl;
214 class AalCameraFlashControl;
215@@ -69,6 +70,8 @@
216
217 bool connectCamera();
218 void disconnectCamera();
219+ void startPreview();
220+ void stopPreview();
221
222 bool isCameraActive() const;
223 bool isBackCameraUsed() const;
224@@ -76,8 +79,8 @@
225 void enablePhotoMode();
226 void enableVideoMode();
227
228- bool isReady() const;
229 bool isRecording() const;
230+ QSize selectSizeWithAspectRatio(const QList<QSize> &sizes, float targetAspectRatio) const;
231
232 static AalCameraService *instance() { return m_service; }
233
234
235=== modified file 'src/aalimagecapturecontrol.cpp'
236--- src/aalimagecapturecontrol.cpp 2015-07-06 18:22:43 +0000
237+++ src/aalimagecapturecontrol.cpp 2015-11-17 15:24:47 +0000
238@@ -43,9 +43,6 @@
239 m_lastRequestId(0),
240 m_ready(false),
241 m_pendingCaptureFile(),
242- m_photoWidth(320),
243- m_photoHeight(240),
244- m_aspectRatio(0.0),
245 m_screenAspectRatio(0.0),
246 m_audioPlayer(new QMediaPlayer(this))
247 {
248@@ -141,36 +138,6 @@
249 {
250 Q_UNUSED(control);
251
252- // Set the optimal image resolution that will be used by the camera
253- QImageEncoderSettings settings;
254- AalImageEncoderControl *imageEncoderControl = AalCameraService::instance()->imageEncoderControl();
255- float imageAspectRatio = 0.0, thumbnailAspectRatio = 0.0;
256- if (!imageEncoderControl->supportedResolutions(settings).empty()) {
257- const QSize s = chooseOptimalSize(imageEncoderControl->supportedResolutions(settings));
258- imageAspectRatio = (float)s.width() / (float)s.height();
259- qDebug() << "Setting image resolution: " << s;
260- qDebug() << "Image aspect ratio: " << imageAspectRatio;
261- imageEncoderControl->setSize(s);
262- }
263- else
264- qWarning() << "No supported resolutions detected for currently selected camera device." << endl;
265-
266- // Set the optimal thumbnail image resolution that will be saved to the JPEG file
267- if (!imageEncoderControl->supportedThumbnailResolutions(settings).empty()) {
268- const QSize s = chooseOptimalSize(imageEncoderControl->supportedThumbnailResolutions(settings), false);
269- thumbnailAspectRatio = (float)s.width() / (float)s.height();
270- qDebug() << "Setting thumbnail resolution: " << s;
271- qDebug() << "Thumbnail aspect ratio: " << thumbnailAspectRatio;
272- imageEncoderControl->setThumbnailSize(s);
273- }
274- else
275- qWarning() << "No supported resolutions detected for currently selected camera device." << endl;
276-
277- // Thumbnails will appear squashed or stretched if not the same aspect ratio as the original image.
278- // This will most likely be an incorrect size list supplied to qtubuntu-camera from the camera driver.
279- if (imageAspectRatio != thumbnailAspectRatio)
280- qWarning() << "** The image and thumbnail aspect ratios are not equal. Thumbnails will display wrong!";
281-
282 listener->on_msg_shutter_cb = &AalImageCaptureControl::shutterCB;
283 listener->on_data_compressed_image_cb = &AalImageCaptureControl::saveJpegCB;
284
285@@ -196,102 +163,12 @@
286 return !m_pendingCaptureFile.isNull();
287 }
288
289-float AalImageCaptureControl::getAspectRatio() const
290-{
291- return m_aspectRatio;
292-}
293-
294 void AalImageCaptureControl::shutter()
295 {
296 m_audioPlayer->play();
297 Q_EMIT imageExposed(m_lastRequestId);
298 }
299
300-QSize AalImageCaptureControl::chooseOptimalSize(const QList<QSize> &sizes, bool updateAspectRatio)
301-{
302- QSize optimalSize;
303- long optimalPixels = 0;
304-
305- if (!sizes.empty()) {
306- getPriorityAspectRatios();
307- float aspectRatio = m_prioritizedAspectRatios.front();
308- if (updateAspectRatio)
309- m_aspectRatio = aspectRatio;
310-
311- // Loop over all reported camera resolutions until we find the highest
312- // one that matches the current prioritized aspect ratio. If it doesn't
313- // find one on the current aspect ration, it selects the next ratio and
314- // tries again.
315- QList<float>::const_iterator ratioIt = m_prioritizedAspectRatios.begin();
316- while (ratioIt != m_prioritizedAspectRatios.end()) {
317- // Don't update the aspect ratio when using this function for finding
318- // the optimal thumbnail size as it will affect the preview window size
319- if (updateAspectRatio)
320- m_aspectRatio = (*ratioIt);
321- else
322- aspectRatio = (*ratioIt);
323-
324- QList<QSize>::const_iterator it = sizes.begin();
325- while (it != sizes.end()) {
326- const float ratio = (float)(*it).width() / (float)(*it).height();
327- const long pixels = ((long)((*it).width())) * ((long)((*it).height()));
328- const float EPSILON = 10e-3;
329- if (fabs(ratio - aspectRatio) < EPSILON && pixels > optimalPixels) {
330- optimalSize = *it;
331- optimalPixels = pixels;
332- }
333- ++it;
334- }
335- if (optimalPixels > 0) break;
336- ++ratioIt;
337- }
338- }
339-
340- return optimalSize;
341-}
342-
343-float AalImageCaptureControl::getScreenAspectRatio()
344-{
345- // Only get the screen aspect ratio once, otherwise use the cached copy
346- if (m_screenAspectRatio == 0.0) {
347- // Get screen resolution.
348- QScreen *screen = QGuiApplication::primaryScreen();
349- Q_ASSERT(!screen);
350- const int kScreenWidth = screen->geometry().width();
351- const int kScreenHeight = screen->geometry().height();
352- Q_ASSERT(kScreenWidth > 0 && kScreenHeight > 0);
353-
354- m_screenAspectRatio = (kScreenWidth > kScreenHeight) ?
355- ((float)kScreenWidth / (float)kScreenHeight) : ((float)kScreenHeight / (float)kScreenWidth);
356- }
357-
358- return m_screenAspectRatio;
359-}
360-
361-void AalImageCaptureControl::getPriorityAspectRatios()
362-{
363- m_prioritizedAspectRatios.clear();
364-
365- if (m_service->isBackCameraUsed()) {
366- if (m_screenAspectRatio > 0.0f) {
367- m_prioritizedAspectRatios.append(getScreenAspectRatio());
368- }
369- // Prioritized list of aspect ratios for the back camera
370- const float backAspectRatios[4] = { 16.0f/9.0f, 3.0f/2.0f, 4.0f/3.0f, 5.0f/4.0f };
371- for (uint8_t i=0; i<4; ++i) {
372- if (!m_prioritizedAspectRatios.contains(backAspectRatios[i])) {
373- m_prioritizedAspectRatios.append(backAspectRatios[i]);
374- }
375- }
376- } else {
377- // Prioritized list of aspect ratios for the front camera
378- const float frontAspectRatios[4] = { 4.0f/3.0f, 5.0f/4.0f, 16.0f/9.0f, 3.0f/2.0f };
379- for (uint8_t i=0; i<4; ++i) {
380- m_prioritizedAspectRatios.append(frontAspectRatios[i]);
381- }
382- }
383-}
384-
385 bool AalImageCaptureControl::updateJpegMetadata(void* data, uint32_t dataSize, QTemporaryFile* destination)
386 {
387 if (data == 0 || destination == 0) return false;
388
389=== modified file 'src/aalimagecapturecontrol.h'
390--- src/aalimagecapturecontrol.h 2014-12-02 20:56:46 +0000
391+++ src/aalimagecapturecontrol.h 2015-11-17 15:24:47 +0000
392@@ -52,10 +52,6 @@
393
394 bool isCaptureRunning() const;
395
396- /// Find the highest optimal aspect ratio resolution, which depends
397- /// on the type of camera currently selected:
398- float getAspectRatio() const;
399-
400 public Q_SLOTS:
401 void init(CameraControl *control, CameraControlListener *listener);
402 void onPreviewReady();
403@@ -64,9 +60,6 @@
404 void shutter();
405
406 private:
407- QSize chooseOptimalSize(const QList<QSize> &sizes, bool updateAspectRatio = true);
408- float getScreenAspectRatio();
409- void getPriorityAspectRatios();
410 void saveJpeg(void* data, uint32_t dataSize);
411 bool updateJpegMetadata(void* data, uint32_t dataSize, QTemporaryFile* destination);
412
413@@ -76,9 +69,6 @@
414 StorageManager m_storageManager;
415 bool m_ready;
416 QString m_pendingCaptureFile;
417- int m_photoWidth;
418- int m_photoHeight;
419- float m_aspectRatio;
420 float m_screenAspectRatio;
421 /// Maintains a list of highest priority aspect ratio to lowest, for the
422 /// currently selected camera
423
424=== modified file 'src/aalimageencodercontrol.cpp'
425--- src/aalimageencodercontrol.cpp 2015-01-28 14:11:53 +0000
426+++ src/aalimageencodercontrol.cpp 2015-11-17 15:24:47 +0000
427@@ -15,12 +15,17 @@
428 */
429
430 #include "aalimageencodercontrol.h"
431+#include "aalcameracontrol.h"
432+#include "aalviewfindersettingscontrol.h"
433+#include "aalvideoencodersettingscontrol.h"
434+#include "aalimagecapturecontrol.h"
435 #include "aalcameraservice.h"
436
437 #include <hybris/camera/camera_compatibility_layer_capabilities.h>
438
439 #include <unistd.h>
440
441+#include <QCamera>
442 #include <QDebug>
443
444 AalImageEncoderControl::AalImageEncoderControl(AalCameraService *service, QObject *parent)
445@@ -63,7 +68,7 @@
446
447 // resolution
448 if (!settings.resolution().isNull()) {
449- m_encoderSettings.setResolution(settings.resolution());
450+ setSize(settings.resolution());
451 }
452
453 // encoding options
454@@ -94,6 +99,11 @@
455 return m_availableThumbnailSizes;
456 }
457
458+float AalImageEncoderControl::getAspectRatio() const
459+{
460+ return (float)m_currentSize.width() / (float)m_currentSize.height();
461+}
462+
463 void AalImageEncoderControl::init(CameraControl *control)
464 {
465 Q_ASSERT(control != NULL);
466@@ -106,47 +116,60 @@
467 int jpegQuality;
468 android_camera_get_jpeg_quality(control, &jpegQuality);
469 m_encoderSettings.setQuality(jpegQualityToQtEncodingQuality(jpegQuality));
470+
471+ if (m_availableSizes.empty()) {
472+ qWarning() << "(AalImageEncoderControl::init) No supported resolutions detected for currently selected camera device." << endl;
473+ return;
474+ }
475+
476+ if (!m_currentSize.isValid() || !m_availableSizes.contains(m_currentSize)) {
477+ setSize(m_availableSizes.last());
478+ } else {
479+ setSize(m_currentSize);
480+ }
481 }
482
483-void AalImageEncoderControl::setSize(const QSize &size)
484+bool AalImageEncoderControl::setSize(const QSize &size)
485 {
486 CameraControl *cc = m_service->androidControl();
487 if (!cc) {
488 m_currentSize = size;
489- return;
490+ m_encoderSettings.setResolution(m_currentSize);
491+ return true;
492 }
493
494 if (!m_availableSizes.contains(size)) {
495- qWarning() << "Size " << size << "is not supported by the camera";
496- qWarning() << "Supported sizes are: " << m_availableSizes;
497- return;
498+ qWarning() << "(AalImageEncoderControl::setSize) Size " << size << "is not supported by the camera";
499+ qWarning() << "(AalImageEncoderControl::setSize) Supported sizes are: " << m_availableSizes;
500+ return false;
501 }
502
503 m_currentSize = size;
504-
505- android_camera_set_picture_size(cc, size.width(), size.height());
506-}
507-
508-/*!
509- * \brief AalImageEncoderControl::setThumbnailSize sets the resolution of JPEG thumbnail
510- */
511-void AalImageEncoderControl::setThumbnailSize(const QSize &size)
512-{
513- CameraControl *cc = m_service->androidControl();
514- if (!cc) {
515- m_currentThumbnailSize = size;
516- return;
517- }
518-
519- if (!m_availableThumbnailSizes.contains(size)) {
520- qWarning() << "Thumbnail size " << size << "is not supported by the camera";
521- qWarning() << "Supported thumbnail sizes are: " << m_availableThumbnailSizes;
522- return;
523- }
524-
525- m_currentThumbnailSize = size;
526-
527- android_camera_set_thumbnail_size(cc, size.width(), size.height());
528+ m_encoderSettings.setResolution(m_currentSize);
529+ if (m_service->cameraControl()->captureMode() == QCamera::CaptureStillImage) {
530+ m_service->viewfinderControl()->setAspectRatio(getAspectRatio());
531+ }
532+
533+ // Select m_currentThumbnailSize so that its aspect ratio is the same
534+ // as m_currentSize's aspect ratio
535+ float imageAspectRatio = getAspectRatio();
536+ float thumbnailAspectRatio;
537+
538+ // Set the optimal thumbnail image resolution that will be saved to the JPEG file
539+ if (!m_availableThumbnailSizes.empty()) {
540+ m_currentThumbnailSize = m_service->selectSizeWithAspectRatio(m_availableThumbnailSizes, imageAspectRatio);
541+ thumbnailAspectRatio = (float)m_currentThumbnailSize.width() / (float)m_currentThumbnailSize.height();
542+ }
543+
544+ // Thumbnails will appear squashed or stretched if not the same aspect ratio as the original image.
545+ // This will most likely be an incorrect size list supplied to qtubuntu-camera from the camera driver.
546+ if (imageAspectRatio != thumbnailAspectRatio) {
547+ qWarning() << "(AalImageEncoderControl::setSize) ** Image and thumbnail aspect ratios are different. Thumbnails will look wrong!";
548+ }
549+
550+ android_camera_set_picture_size(cc, m_currentSize.width(), m_currentSize.height());
551+ android_camera_set_thumbnail_size(cc, m_currentThumbnailSize.width(), m_currentThumbnailSize.height());
552+ return true;
553 }
554
555 void AalImageEncoderControl::resetAllSettings()
556
557=== modified file 'src/aalimageencodercontrol.h'
558--- src/aalimageencodercontrol.h 2014-11-24 10:58:09 +0000
559+++ src/aalimageencodercontrol.h 2015-11-17 15:24:47 +0000
560@@ -37,10 +37,9 @@
561 QStringList supportedImageCodecs() const;
562 QList<QSize> supportedResolutions(const QImageEncoderSettings &settings, bool *continuous = 0) const;
563 QList<QSize> supportedThumbnailResolutions(const QImageEncoderSettings &settings, bool *continuous = 0) const;
564+ float getAspectRatio() const;
565
566 void init(CameraControl *control);
567- void setSize(const QSize &size);
568- void setThumbnailSize(const QSize &size);
569 void resetAllSettings();
570
571 void enablePhotoMode();
572@@ -56,6 +55,7 @@
573 QSize m_currentThumbnailSize;
574 QImageEncoderSettings m_encoderSettings;
575
576+ bool setSize(const QSize &size);
577 void getPictureSize(int width, int height);
578 void getThumbnailSize(int width, int height);
579 QMultimedia::EncodingQuality jpegQualityToQtEncodingQuality(int jpegQuality);
580
581=== modified file 'src/aalvideodeviceselectorcontrol.cpp'
582--- src/aalvideodeviceselectorcontrol.cpp 2014-07-28 12:52:45 +0000
583+++ src/aalvideodeviceselectorcontrol.cpp 2015-11-17 15:24:47 +0000
584@@ -86,8 +86,10 @@
585 m_service->imageEncoderControl()->resetAllSettings();
586 m_service->videoEncoderControl()->resetAllSettings();
587 m_currentDevice = index;
588- if (m_service->isCameraActive())
589+ if (m_service->isCameraActive()) {
590 m_service->connectCamera();
591+ m_service->startPreview();
592+ }
593
594 Q_EMIT selectedDeviceChanged(m_currentDevice);
595 Q_EMIT selectedDeviceChanged(deviceName(m_currentDevice));
596
597=== modified file 'src/aalvideoencodersettingscontrol.cpp'
598--- src/aalvideoencodersettingscontrol.cpp 2013-07-24 06:50:58 +0000
599+++ src/aalvideoencodersettingscontrol.cpp 2015-11-17 15:24:47 +0000
600@@ -16,10 +16,13 @@
601
602 #include "aalvideoencodersettingscontrol.h"
603 #include "aalcameraservice.h"
604+#include "aalcameracontrol.h"
605 #include "aalviewfindersettingscontrol.h"
606
607 #include <hybris/camera/camera_compatibility_layer_capabilities.h>
608
609+#include <QCamera>
610+
611 const QSize AalVideoEncoderSettingsControl::DEFAULT_SIZE = QSize(1280,720);
612 const int AalVideoEncoderSettingsControl::DEFAULT_FPS = 30;
613 const QString AalVideoEncoderSettingsControl::DEFAULT_CODEC = QString("H.264");
614@@ -49,8 +52,12 @@
615 if (supportedFrameRates(settings, &continuous).contains(settings.frameRate()))
616 m_settings.setFrameRate(settings.frameRate());
617
618- if (supportedResolutions(settings, &continuous).contains(settings.resolution()))
619+ if (supportedResolutions(settings, &continuous).contains(settings.resolution())) {
620 m_settings.setResolution(settings.resolution());
621+ if (m_service->cameraControl()->captureMode() == QCamera::CaptureVideo) {
622+ m_service->viewfinderControl()->setAspectRatio(getAspectRatio());
623+ }
624+ }
625
626 // FIXME support more options
627 }
628@@ -136,6 +143,9 @@
629
630 if (!m_availableSizes.contains(m_settings.resolution()) && !m_availableSizes.empty()) {
631 m_settings.setResolution(m_availableSizes[0]);
632+ if (m_service->cameraControl()->captureMode() == QCamera::CaptureVideo) {
633+ m_service->viewfinderControl()->setAspectRatio(getAspectRatio());
634+ }
635 }
636 }
637
638
639=== modified file 'src/aalvideorenderercontrol.cpp'
640--- src/aalvideorenderercontrol.cpp 2014-09-05 15:20:34 +0000
641+++ src/aalvideorenderercontrol.cpp 2015-11-17 15:24:47 +0000
642@@ -129,9 +129,6 @@
643
644 void AalVideoRendererControl::stopPreview()
645 {
646- if (!m_viewFinderRunning || !m_surface)
647- return;
648-
649 m_viewFinderRunning = false;
650
651 CameraControl *cc = m_service->androidControl();
652@@ -139,7 +136,7 @@
653 android_camera_stop_preview(cc);
654 }
655
656- if (m_surface->isActive())
657+ if (m_surface && m_surface->isActive())
658 m_surface->stop();
659
660 m_frameCount = 0;
661
662=== modified file 'src/aalviewfindersettingscontrol.cpp'
663--- src/aalviewfindersettingscontrol.cpp 2013-07-16 13:09:15 +0000
664+++ src/aalviewfindersettingscontrol.cpp 2015-11-17 15:24:47 +0000
665@@ -20,8 +20,6 @@
666
667 #include <QDebug>
668
669-#include <cmath>
670-
671 #include <hybris/camera/camera_compatibility_layer_capabilities.h>
672
673 AalViewfinderSettingsControl::AalViewfinderSettingsControl(AalCameraService *service, QObject *parent)
674@@ -111,15 +109,9 @@
675 m_currentSize = size;
676
677 AalVideoRendererControl *videoRenderer = m_service->videoOutputControl();
678- bool vfRunning = videoRenderer->isViewfinderRunning();
679-
680- if (vfRunning)
681- videoRenderer->stopPreview();
682-
683+ videoRenderer->stopPreview();
684 android_camera_set_preview_size(cc, m_currentSize.width(), m_currentSize.height());
685-
686- if (vfRunning)
687- videoRenderer->startPreview();
688+ videoRenderer->startPreview();
689 }
690
691 QSize AalViewfinderSettingsControl::currentSize() const
692@@ -172,7 +164,9 @@
693 }
694
695 // Choose optimal resolution based on the current camera's aspect ratio
696- m_currentSize = chooseOptimalSize(m_availableSizes);
697+ if (m_currentSize.isEmpty()) {
698+ m_currentSize = chooseOptimalSize(m_availableSizes);
699+ }
700 android_camera_set_preview_size(control, m_currentSize.width(), m_currentSize.height());
701
702 android_camera_get_preview_fps_range(control, &m_minFPS, &m_maxFPS);
703@@ -211,16 +205,8 @@
704 if (m_aspectRatio == 0) {
705 // There are resolutions supported, choose one non-optimal one):
706 return sizes[1];
707- }
708-
709- QList<QSize>::const_iterator it = sizes.begin();
710- while (it != sizes.end()) {
711- const float ratio = (float)(*it).width() / (float)(*it).height();
712- const float EPSILON = 10e-3;
713- if (fabs(ratio - m_aspectRatio) < EPSILON) {
714- return *it;
715- }
716- ++it;
717+ } else {
718+ return m_service->selectSizeWithAspectRatio(sizes, m_aspectRatio);
719 }
720 }
721
722
723=== modified file 'src/aalviewfindersettingscontrol.h'
724--- src/aalviewfindersettingscontrol.h 2013-06-21 15:57:39 +0000
725+++ src/aalviewfindersettingscontrol.h 2015-11-17 15:24:47 +0000
726@@ -35,7 +35,6 @@
727 void setViewfinderParameter(ViewfinderParameter parameter, const QVariant & value);
728 QVariant viewfinderParameter(ViewfinderParameter parameter) const;
729
730- void setSize(const QSize &size);
731 QSize currentSize() const;
732 const QList<QSize> &supportedSizes() const;
733
734@@ -47,6 +46,7 @@
735 static void sizeCB(void* ctx, int width, int height);
736
737 private:
738+ void setSize(const QSize &size);
739 QSize chooseOptimalSize(const QList<QSize> &sizes) const;
740
741 AalCameraService *m_service;
742
743=== modified file 'src/src.pro'
744--- src/src.pro 2015-06-24 04:36:42 +0000
745+++ src/src.pro 2015-11-17 15:24:47 +0000
746@@ -9,16 +9,8 @@
747 target.path += $$[QT_INSTALL_PLUGINS]/$${PLUGIN_TYPE}
748 INSTALLS = target
749
750-INCLUDEPATH += /usr/include/libqtubuntu-media-signals
751-LIBS += \
752- -lcamera \
753- -lmedia \
754- -lqtubuntu-media-signals \
755- -lpulse \
756- -lpulse-simple
757-
758 CONFIG += link_pkgconfig
759-PKGCONFIG += exiv2
760+PKGCONFIG += exiv2 libqtubuntu-media-signals libmedia libcamera hybris-egl-platform libpulse-simple
761
762 OTHER_FILES += aalcamera.json
763
764
765=== modified file 'unittests/aalcameracontrol/aalcameraservice.cpp'
766--- unittests/aalcameracontrol/aalcameraservice.cpp 2013-07-26 16:46:16 +0000
767+++ unittests/aalcameracontrol/aalcameraservice.cpp 2015-11-17 15:24:47 +0000
768@@ -54,6 +54,14 @@
769 {
770 }
771
772+void AalCameraService::startPreview()
773+{
774+}
775+
776+void AalCameraService::stopPreview()
777+{
778+}
779+
780 bool AalCameraService::isCameraActive() const
781 {
782 return true;
783@@ -81,3 +89,10 @@
784 void AalCameraService::updateCaptureReady()
785 {
786 }
787+
788+QSize AalCameraService::selectSizeWithAspectRatio(const QList<QSize> &sizes, float targetAspectRatio) const
789+{
790+ Q_UNUSED(sizes);
791+ Q_UNUSED(targetAspectRatio);
792+ return QSize();
793+}
794
795=== modified file 'unittests/aalcameraexposurecontrol/aalcameraservice.cpp'
796--- unittests/aalcameraexposurecontrol/aalcameraservice.cpp 2014-07-15 12:38:55 +0000
797+++ unittests/aalcameraexposurecontrol/aalcameraservice.cpp 2015-11-17 15:24:47 +0000
798@@ -66,6 +66,14 @@
799 android_camera_disconnect(m_androidControl);
800 }
801
802+void AalCameraService::startPreview()
803+{
804+}
805+
806+void AalCameraService::stopPreview()
807+{
808+}
809+
810 void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener)
811 {
812 m_exposureControl->init(camControl, listener);
813@@ -74,3 +82,10 @@
814 void AalCameraService::updateCaptureReady()
815 {
816 }
817+
818+QSize AalCameraService::selectSizeWithAspectRatio(const QList<QSize> &sizes, float targetAspectRatio) const
819+{
820+ Q_UNUSED(sizes);
821+ Q_UNUSED(targetAspectRatio);
822+ return QSize();
823+}
824
825=== modified file 'unittests/aalcameraflashcontrol/aalcameraservice.cpp'
826--- unittests/aalcameraflashcontrol/aalcameraservice.cpp 2013-08-05 07:29:41 +0000
827+++ unittests/aalcameraflashcontrol/aalcameraservice.cpp 2015-11-17 15:24:47 +0000
828@@ -57,6 +57,14 @@
829 {
830 }
831
832+void AalCameraService::startPreview()
833+{
834+}
835+
836+void AalCameraService::stopPreview()
837+{
838+}
839+
840 void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener)
841 {
842 Q_UNUSED(camControl);
843@@ -76,3 +84,10 @@
844 void AalCameraService::updateCaptureReady()
845 {
846 }
847+
848+QSize AalCameraService::selectSizeWithAspectRatio(const QList<QSize> &sizes, float targetAspectRatio) const
849+{
850+ Q_UNUSED(sizes);
851+ Q_UNUSED(targetAspectRatio);
852+ return QSize();
853+}
854
855=== modified file 'unittests/aalcamerafocuscontrol/aalcameraservice.cpp'
856--- unittests/aalcamerafocuscontrol/aalcameraservice.cpp 2013-02-11 15:56:21 +0000
857+++ unittests/aalcamerafocuscontrol/aalcameraservice.cpp 2015-11-17 15:24:47 +0000
858@@ -54,6 +54,14 @@
859 {
860 }
861
862+void AalCameraService::startPreview()
863+{
864+}
865+
866+void AalCameraService::stopPreview()
867+{
868+}
869+
870 void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener)
871 {
872 Q_UNUSED(camControl);
873@@ -63,3 +71,10 @@
874 void AalCameraService::updateCaptureReady()
875 {
876 }
877+
878+QSize AalCameraService::selectSizeWithAspectRatio(const QList<QSize> &sizes, float targetAspectRatio) const
879+{
880+ Q_UNUSED(sizes);
881+ Q_UNUSED(targetAspectRatio);
882+ return QSize();
883+}
884
885=== modified file 'unittests/aalcamerazoomcontrol/aalcameraservice.cpp'
886--- unittests/aalcamerazoomcontrol/aalcameraservice.cpp 2013-07-23 16:02:22 +0000
887+++ unittests/aalcamerazoomcontrol/aalcameraservice.cpp 2015-11-17 15:24:47 +0000
888@@ -68,6 +68,14 @@
889 android_camera_disconnect(m_androidControl);
890 }
891
892+void AalCameraService::startPreview()
893+{
894+}
895+
896+void AalCameraService::stopPreview()
897+{
898+}
899+
900 void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener)
901 {
902 m_zoomControl->init(camControl, listener);
903@@ -76,3 +84,10 @@
904 void AalCameraService::updateCaptureReady()
905 {
906 }
907+
908+QSize AalCameraService::selectSizeWithAspectRatio(const QList<QSize> &sizes, float targetAspectRatio) const
909+{
910+ Q_UNUSED(sizes);
911+ Q_UNUSED(targetAspectRatio);
912+ return QSize();
913+}
914
915=== modified file 'unittests/aalimagecapturecontrol/aalcameraservice.cpp'
916--- unittests/aalimagecapturecontrol/aalcameraservice.cpp 2013-02-14 19:37:36 +0000
917+++ unittests/aalimagecapturecontrol/aalcameraservice.cpp 2015-11-17 15:24:47 +0000
918@@ -54,6 +54,14 @@
919 {
920 }
921
922+void AalCameraService::startPreview()
923+{
924+}
925+
926+void AalCameraService::stopPreview()
927+{
928+}
929+
930 void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener)
931 {
932 Q_UNUSED(camControl);
933@@ -73,3 +81,10 @@
934 void AalCameraService::updateCaptureReady()
935 {
936 }
937+
938+QSize AalCameraService::selectSizeWithAspectRatio(const QList<QSize> &sizes, float targetAspectRatio) const
939+{
940+ Q_UNUSED(sizes);
941+ Q_UNUSED(targetAspectRatio);
942+ return QSize();
943+}
944
945=== modified file 'unittests/aalimagecapturecontrol/aalimageencodercontrol.cpp'
946--- unittests/aalimagecapturecontrol/aalimageencodercontrol.cpp 2014-11-24 11:16:57 +0000
947+++ unittests/aalimagecapturecontrol/aalimageencodercontrol.cpp 2015-11-17 15:24:47 +0000
948@@ -76,14 +76,10 @@
949 Q_UNUSED(control);
950 }
951
952-void AalImageEncoderControl::setSize(const QSize &size)
953-{
954- Q_UNUSED(size);
955-}
956-
957-void AalImageEncoderControl::setThumbnailSize(const QSize &size)
958-{
959- Q_UNUSED(size);
960+bool AalImageEncoderControl::setSize(const QSize &size)
961+{
962+ Q_UNUSED(size);
963+ return true;
964 }
965
966 void AalImageEncoderControl::resetAllSettings()
967
968=== modified file 'unittests/aalimagecapturecontrol/tst_aalimagecapturecontrol.cpp'
969--- unittests/aalimagecapturecontrol/tst_aalimagecapturecontrol.cpp 2014-09-29 10:05:25 +0000
970+++ unittests/aalimagecapturecontrol/tst_aalimagecapturecontrol.cpp 2015-11-17 15:24:47 +0000
971@@ -31,11 +31,6 @@
972 void initTestCase();
973 void cleanupTestCase();
974
975- void chooseOptimalSize16by9();
976- void chooseOptimalSizeEmpty();
977-
978- void priorityAspectRatio();
979-
980 void updateEXIF();
981
982 private:
983@@ -57,45 +52,6 @@
984 delete m_service;
985 }
986
987-void tst_AalImageCaptureControl::chooseOptimalSize16by9()
988-{
989- Q_ASSERT(m_service->isBackCameraUsed());
990-
991- m_icControl->m_aspectRatio = 16.0f / 9.0f;
992- QList<QSize> resolutions;
993- resolutions.append(QSize(1920, 1080));
994- resolutions.append(QSize(1280, 720));
995- resolutions.append(QSize(960, 720));
996-
997- QCOMPARE(m_icControl->chooseOptimalSize(resolutions), QSize(1920, 1080));
998-}
999-
1000-void tst_AalImageCaptureControl::chooseOptimalSizeEmpty()
1001-{
1002- m_icControl->m_aspectRatio = 4.0f / 3.0f;
1003- QList<QSize> resolutions;
1004-
1005- QCOMPARE(m_icControl->chooseOptimalSize(resolutions), QSize());
1006-}
1007-
1008-void tst_AalImageCaptureControl::priorityAspectRatio()
1009-{
1010- Q_ASSERT(m_service->isBackCameraUsed());
1011-
1012- QList<float> backAspectRatios;
1013- backAspectRatios.append(16.0f / 9.0f);
1014- backAspectRatios.append(15.0f / 10.0f);
1015- backAspectRatios.append(4.0f / 3.0f);
1016- backAspectRatios.append(5.0f / 4.0f);
1017- m_icControl->getPriorityAspectRatios();
1018- for (uint8_t i=0; i<4; ++i) {
1019- const float EPSILON = 10e-2;
1020- qDebug() << "m_icControl->m_prioritizedAspectRatios[i]: " << m_icControl->m_prioritizedAspectRatios[i] << endl;
1021- qDebug() << "backAspectRatios[i]: " << backAspectRatios[i] << endl;
1022- Q_ASSERT(fabs(m_icControl->m_prioritizedAspectRatios[i] - backAspectRatios[i]) < EPSILON);
1023- }
1024-}
1025-
1026 void tst_AalImageCaptureControl::updateEXIF()
1027 {
1028 bool result;
1029
1030=== modified file 'unittests/aalvideodeviceselectorcontrol/aalcameraservice.cpp'
1031--- unittests/aalvideodeviceselectorcontrol/aalcameraservice.cpp 2013-08-01 10:41:04 +0000
1032+++ unittests/aalvideodeviceselectorcontrol/aalcameraservice.cpp 2015-11-17 15:24:47 +0000
1033@@ -54,6 +54,14 @@
1034 {
1035 }
1036
1037+void AalCameraService::startPreview()
1038+{
1039+}
1040+
1041+void AalCameraService::stopPreview()
1042+{
1043+}
1044+
1045 bool AalCameraService::isCameraActive() const
1046 {
1047 return true;
1048@@ -65,11 +73,6 @@
1049 Q_UNUSED(listener);
1050 }
1051
1052-bool AalCameraService::isReady() const
1053-{
1054- return true;
1055-}
1056-
1057 bool AalCameraService::isRecording() const
1058 {
1059 return false;
1060@@ -78,3 +81,10 @@
1061 void AalCameraService::updateCaptureReady()
1062 {
1063 }
1064+
1065+QSize AalCameraService::selectSizeWithAspectRatio(const QList<QSize> &sizes, float targetAspectRatio) const
1066+{
1067+ Q_UNUSED(sizes);
1068+ Q_UNUSED(targetAspectRatio);
1069+ return QSize();
1070+}
1071
1072=== modified file 'unittests/aalvideodeviceselectorcontrol/aalimageencodercontrol.cpp'
1073--- unittests/aalvideodeviceselectorcontrol/aalimageencodercontrol.cpp 2014-10-27 17:25:50 +0000
1074+++ unittests/aalvideodeviceselectorcontrol/aalimageencodercontrol.cpp 2015-11-17 15:24:47 +0000
1075@@ -61,9 +61,10 @@
1076 Q_UNUSED(control);
1077 }
1078
1079-void AalImageEncoderControl::setSize(const QSize &size)
1080+bool AalImageEncoderControl::setSize(const QSize &size)
1081 {
1082 Q_UNUSED(size);
1083+ return true;
1084 }
1085
1086 void AalImageEncoderControl::resetAllSettings()
1087
1088=== modified file 'unittests/aalviewfindersettingscontrol/aalcameraservice.cpp'
1089--- unittests/aalviewfindersettingscontrol/aalcameraservice.cpp 2013-02-11 15:56:21 +0000
1090+++ unittests/aalviewfindersettingscontrol/aalcameraservice.cpp 2015-11-17 15:24:47 +0000
1091@@ -15,6 +15,7 @@
1092 */
1093
1094 #include "aalcameraservice.h"
1095+#include <cmath>
1096
1097 AalCameraService *AalCameraService::m_service = 0;
1098
1099@@ -54,6 +55,14 @@
1100 {
1101 }
1102
1103+void AalCameraService::startPreview()
1104+{
1105+}
1106+
1107+void AalCameraService::stopPreview()
1108+{
1109+}
1110+
1111 void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener)
1112 {
1113 Q_UNUSED(camControl);
1114@@ -73,3 +82,28 @@
1115 void AalCameraService::updateCaptureReady()
1116 {
1117 }
1118+
1119+QSize AalCameraService::selectSizeWithAspectRatio(const QList<QSize> &sizes, float targetAspectRatio) const
1120+{
1121+ QSize selectedSize;
1122+ long selectedPixelCount = 0;
1123+ const float EPSILON = 0.02;
1124+
1125+ if (!sizes.empty()) {
1126+ // Loop over all sizes until we find the highest one that matches targetAspectRatio.
1127+ QList<QSize>::const_iterator it = sizes.begin();
1128+ while (it != sizes.end()) {
1129+ QSize size = *it;
1130+ const float aspectRatio = (float)size.width() / (float)size.height();
1131+ const long pixelCount = (long)size.width() * (long)size.height();
1132+ if (fabs(aspectRatio - targetAspectRatio) < EPSILON && pixelCount > selectedPixelCount) {
1133+ selectedSize = size;
1134+ selectedPixelCount = pixelCount;
1135+ }
1136+ ++it;
1137+ }
1138+ }
1139+
1140+ return selectedSize;
1141+}
1142+
1143
1144=== modified file 'unittests/stubs/aalcameraservice_stub.cpp'
1145--- unittests/stubs/aalcameraservice_stub.cpp 2013-06-22 07:29:20 +0000
1146+++ unittests/stubs/aalcameraservice_stub.cpp 2015-11-17 15:24:47 +0000
1147@@ -65,6 +65,14 @@
1148 {
1149 }
1150
1151+void AalCameraService::startPreview()
1152+{
1153+}
1154+
1155+void AalCameraService::stopPreview()
1156+{
1157+}
1158+
1159 void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener)
1160 {
1161 delete m_androidControl;

Subscribers

People subscribed via source and target branches