Merge lp:qtubuntu-camera/staging into lp:qtubuntu-camera
- staging
- Merge into trunk
Proposed by
Florian Boucault
Status: | Merged |
---|---|
Approved by: | Florian Boucault |
Approved revision: | 179 |
Merged at revision: | 157 |
Proposed branch: | lp:qtubuntu-camera/staging |
Merge into: | lp:qtubuntu-camera |
Diff against target: |
1363 lines (+394/-621) 20 files modified
aalCamera.pro (+0/-1) src/aalcamerafocuscontrol.cpp (+1/-1) src/aalimagecapturecontrol.cpp (+63/-133) src/aalimagecapturecontrol.h (+8/-4) src/storagemanager.cpp (+173/-1) src/storagemanager.h (+29/-5) unittests/aalcamerafocuscontrol/aalcamerafocuscontrol.pro (+3/-1) unittests/aalcamerafocuscontrol/aalimagecapturecontrol.cpp (+10/-8) unittests/aalcamerafocuscontrol/storagemanager.cpp (+76/-0) unittests/aalcamerafocuscontrol/tst_aalcamerafocuscontrol.cpp (+2/-2) unittests/aalimagecapturecontrol/aalcameraservice.cpp (+0/-99) unittests/aalimagecapturecontrol/aalimagecapturecontrol.pro (+0/-31) unittests/aalimagecapturecontrol/aalimageencodercontrol.cpp (+0/-125) unittests/aalimagecapturecontrol/aalvideorenderercontrol.cpp (+0/-84) unittests/aalimagecapturecontrol/storagemanager.cpp (+0/-50) unittests/aalimagecapturecontrol/tst_aalimagecapturecontrol.cpp (+0/-74) unittests/storagemanager/storagemanager.pro (+5/-0) unittests/storagemanager/tst_storagemanager.cpp (+22/-0) unittests/stubs/storagemanager_stub.cpp (+2/-1) unittests/unittests.pro (+0/-1) |
To merge this branch: | bzr merge lp:qtubuntu-camera/staging |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Ubuntu Phablet Team | Pending | ||
Review via email: mp+286880@code.launchpad.net |
Commit message
New release:
- Performance improvements to minimize the time necessary between when pressing the shutter button and being able to capture the next pitcure. Remove sliding out the preview as a part of this.
Description of the change
To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : | # |
review:
Approve
(continuous-integration)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'aalCamera.pro' |
2 | --- aalCamera.pro 2015-11-12 10:32:24 +0000 |
3 | +++ aalCamera.pro 2016-02-23 11:36:01 +0000 |
4 | @@ -5,5 +5,4 @@ |
5 | SUBDIRS += \ |
6 | src \ |
7 | unittests |
8 | - |
9 | OTHER_FILES += .qmake.conf |
10 | |
11 | === modified file 'src/aalcamerafocuscontrol.cpp' |
12 | --- src/aalcamerafocuscontrol.cpp 2015-10-14 13:54:37 +0000 |
13 | +++ src/aalcamerafocuscontrol.cpp 2016-02-23 11:36:01 +0000 |
14 | @@ -212,7 +212,7 @@ |
15 | int centerX = (point.x() * (2* focusFullSize)) - focusFullSize; |
16 | int maxCenterPosition = focusFullSize - focusRegionSize; |
17 | centerX = std::max(std::min(centerX, maxCenterPosition), -maxCenterPosition); |
18 | - int centerY = -1 * ((point.y() * (2 * focusFullSize)) - focusFullSize); |
19 | + int centerY = (point.y() * (2 * focusFullSize)) - focusFullSize; |
20 | centerY = std::max(std::min(centerY, maxCenterPosition), -maxCenterPosition); |
21 | |
22 | FocusRegion region; |
23 | |
24 | === modified file 'src/aalimagecapturecontrol.cpp' |
25 | --- src/aalimagecapturecontrol.cpp 2016-01-11 15:10:38 +0000 |
26 | +++ src/aalimagecapturecontrol.cpp 2016-02-23 11:36:01 +0000 |
27 | @@ -19,13 +19,14 @@ |
28 | #include "aalimageencodercontrol.h" |
29 | #include "aalmetadatawritercontrol.h" |
30 | #include "aalvideorenderercontrol.h" |
31 | +#include "aalviewfindersettingscontrol.h" |
32 | #include "storagemanager.h" |
33 | |
34 | #include <hybris/camera/camera_compatibility_layer.h> |
35 | #include <hybris/camera/camera_compatibility_layer_capabilities.h> |
36 | -#include <exiv2/exiv2.hpp> |
37 | |
38 | #include <QDir> |
39 | +#include <QObject> |
40 | #include <QFile> |
41 | #include <QFileInfo> |
42 | #include <QMediaPlayer> |
43 | @@ -34,8 +35,7 @@ |
44 | #include <QGuiApplication> |
45 | #include <QScreen> |
46 | #include <QSettings> |
47 | - |
48 | -#include <cmath> |
49 | +#include <QtConcurrent/QtConcurrent> |
50 | |
51 | AalImageCaptureControl::AalImageCaptureControl(AalCameraService *service, QObject *parent) |
52 | : QCameraImageCaptureControl(parent), |
53 | @@ -43,7 +43,7 @@ |
54 | m_cameraControl(service->cameraControl()), |
55 | m_lastRequestId(0), |
56 | m_ready(false), |
57 | - m_pendingCaptureFile(), |
58 | + m_targetFileName(), |
59 | m_captureCancelled(false), |
60 | m_screenAspectRatio(0.0), |
61 | m_audioPlayer(new QMediaPlayer(this)) |
62 | @@ -55,6 +55,9 @@ |
63 | #else |
64 | m_audioPlayer->setAudioRole(QAudio::NotificationRole); |
65 | #endif |
66 | + |
67 | + QObject::connect(&m_storageManager, &StorageManager::previewReady, |
68 | + this, &AalImageCaptureControl::imageCaptured); |
69 | } |
70 | |
71 | AalImageCaptureControl::~AalImageCaptureControl() |
72 | @@ -76,58 +79,24 @@ |
73 | return m_lastRequestId; |
74 | } |
75 | |
76 | + m_targetFileName = fileName; |
77 | m_captureCancelled = false; |
78 | - QFileInfo fi(fileName); |
79 | - if (fileName.isEmpty() || fi.isDir()) { |
80 | - m_pendingCaptureFile = m_storageManager.nextPhotoFileName(fileName); |
81 | - } else { |
82 | - m_pendingCaptureFile = fileName; |
83 | - } |
84 | - bool diskOk = m_storageManager.checkDirectory(m_pendingCaptureFile); |
85 | - if (!diskOk) { |
86 | - emit error(m_lastRequestId, QCameraImageCapture::ResourceError, |
87 | - QString("Won't be able to save file %1 to disk").arg(m_pendingCaptureFile)); |
88 | - return m_lastRequestId; |
89 | - } |
90 | |
91 | AalMetaDataWriterControl* metadataControl = m_service->metadataWriterControl(); |
92 | - |
93 | int rotation = metadataControl->correctedOrientation(); |
94 | android_camera_set_rotation(m_service->androidControl(), rotation); |
95 | |
96 | - QStringList availableMetadata = metadataControl->availableMetaData(); |
97 | - if (availableMetadata.contains("GPSLatitude") && |
98 | - availableMetadata.contains("GPSLongitude") && |
99 | - availableMetadata.contains("GPSTimeStamp")) { |
100 | - float latitude = metadataControl->metaData("GPSLatitude").toFloat(); |
101 | - float longitude = metadataControl->metaData("GPSLongitude").toFloat(); |
102 | - float altitude = 0.0f; |
103 | - if (availableMetadata.contains("GPSAltitude")) { |
104 | - altitude = metadataControl->metaData("GPSAltitude").toFloat(); |
105 | - } |
106 | - QDateTime timestamp = metadataControl->metaData("GPSTimeStamp").toDateTime(); |
107 | - QString processingMethod = metadataControl->metaData("GPSProcessingMethod").toString(); |
108 | - android_camera_set_location(m_service->androidControl(), |
109 | - &latitude, &longitude, &altitude, |
110 | - timestamp.toTime_t(), |
111 | - processingMethod.toLocal8Bit().constData()); |
112 | - } |
113 | - |
114 | android_camera_take_snapshot(m_service->androidControl()); |
115 | |
116 | m_service->updateCaptureReady(); |
117 | |
118 | - m_service->videoOutputControl()->createPreview(); |
119 | - |
120 | - m_service->metadataWriterControl()->clearAllMetaData(); |
121 | - |
122 | return m_lastRequestId; |
123 | } |
124 | |
125 | void AalImageCaptureControl::cancelCapture() |
126 | { |
127 | m_captureCancelled = true; |
128 | - m_pendingCaptureFile.clear(); |
129 | + m_targetFileName.clear(); |
130 | } |
131 | |
132 | void AalImageCaptureControl::shutterCB(void *context) |
133 | @@ -140,7 +109,14 @@ |
134 | void AalImageCaptureControl::saveJpegCB(void *data, uint32_t data_size, void *context) |
135 | { |
136 | Q_UNUSED(context); |
137 | - AalCameraService::instance()->imageCaptureControl()->saveJpeg(data, data_size); |
138 | + |
139 | + // Copy the data buffer so that it is safe to pass it off to another thread, |
140 | + // since it will be destroyed once this function returns |
141 | + QByteArray dataCopy((const char*)data, data_size); |
142 | + |
143 | + QMetaObject::invokeMethod(AalCameraService::instance()->imageCaptureControl(), |
144 | + "saveJpeg", Qt::QueuedConnection, |
145 | + Q_ARG(QByteArray, dataCopy)); |
146 | } |
147 | |
148 | void AalImageCaptureControl::init(CameraControl *control, CameraControlListener *listener) |
149 | @@ -153,12 +129,6 @@ |
150 | connect(m_service->videoOutputControl(), SIGNAL(previewReady()), this, SLOT(onPreviewReady())); |
151 | } |
152 | |
153 | -void AalImageCaptureControl::onPreviewReady() |
154 | -{ |
155 | - // The preview image was fully captured, notify the UI layer |
156 | - Q_EMIT imageCaptured(m_lastRequestId, m_service->videoOutputControl()->preview()); |
157 | -} |
158 | - |
159 | void AalImageCaptureControl::setReady(bool ready) |
160 | { |
161 | if (m_ready != ready) { |
162 | @@ -169,7 +139,7 @@ |
163 | |
164 | bool AalImageCaptureControl::isCaptureRunning() const |
165 | { |
166 | - return !m_pendingCaptureFile.isNull(); |
167 | + return !m_targetFileName.isEmpty(); |
168 | } |
169 | |
170 | void AalImageCaptureControl::shutter() |
171 | @@ -181,96 +151,56 @@ |
172 | Q_EMIT imageExposed(m_lastRequestId); |
173 | } |
174 | |
175 | -bool AalImageCaptureControl::updateJpegMetadata(void* data, uint32_t dataSize, QTemporaryFile* destination) |
176 | -{ |
177 | - if (data == 0 || destination == 0) return false; |
178 | - |
179 | - Exiv2::Image::AutoPtr image; |
180 | - try { |
181 | - image = Exiv2::ImageFactory::open(static_cast<Exiv2::byte*>(data), dataSize); |
182 | - if (!image.get()) { |
183 | - return false; |
184 | - } |
185 | - } catch(const Exiv2::AnyError&) { |
186 | - return false; |
187 | - } |
188 | - |
189 | - try { |
190 | - image->readMetadata(); |
191 | - Exiv2::ExifData ed = image->exifData(); |
192 | - const QString now = QDateTime::currentDateTime().toString("yyyy:MM:dd HH:mm:ss"); |
193 | - ed["Exif.Photo.DateTimeOriginal"].setValue(now.toStdString()); |
194 | - ed["Exif.Photo.DateTimeDigitized"].setValue(now.toStdString()); |
195 | - image->setExifData(ed); |
196 | - image->writeMetadata(); |
197 | - } catch(const Exiv2::AnyError&) { |
198 | - return false; |
199 | - } |
200 | - |
201 | - if (!destination->open()) { |
202 | - return false; |
203 | - } |
204 | - |
205 | - try { |
206 | - Exiv2::BasicIo& io = image->io(); |
207 | - char* modifiedMetadata = reinterpret_cast<char*>(io.mmap()); |
208 | - const long size = io.size(); |
209 | - const qint64 writtenSize = destination->write(modifiedMetadata, size); |
210 | - io.munmap(); |
211 | - destination->close(); |
212 | - return (writtenSize == size); |
213 | - |
214 | - } catch(const Exiv2::AnyError&) { |
215 | - destination->close(); |
216 | - return false; |
217 | - } |
218 | -} |
219 | - |
220 | -void AalImageCaptureControl::saveJpeg(void *data, uint32_t dataSize) |
221 | +void AalImageCaptureControl::saveJpeg(const QByteArray& data) |
222 | { |
223 | if (m_captureCancelled) { |
224 | m_captureCancelled = false; |
225 | return; |
226 | } |
227 | |
228 | - if (m_pendingCaptureFile.isNull() || !m_service->androidControl()) |
229 | - return; |
230 | - |
231 | - QTemporaryFile file; |
232 | - if (!updateJpegMetadata(data, dataSize, &file)) { |
233 | - qWarning() << "Failed to update EXIF timestamps. Picture will be saved as UTC timezone."; |
234 | - if (!file.open()) { |
235 | - emit error(m_lastRequestId, QCameraImageCapture::ResourceError, |
236 | - QString("Could not open temprary file %1").arg(file.fileName())); |
237 | - m_pendingCaptureFile.clear(); |
238 | - m_service->updateCaptureReady(); |
239 | - return; |
240 | - } |
241 | - |
242 | - const qint64 writtenSize = file.write(static_cast<const char*>(data), dataSize); |
243 | - file.close(); |
244 | - if (writtenSize != dataSize) { |
245 | - emit error(m_lastRequestId, QCameraImageCapture::ResourceError, |
246 | - QString("Could not write file %1").arg(file.fileName())); |
247 | - m_pendingCaptureFile.clear(); |
248 | - m_service->updateCaptureReady(); |
249 | - return; |
250 | - } |
251 | - } |
252 | - |
253 | - QFile finalFile(file.fileName()); |
254 | - bool ok = finalFile.rename(m_pendingCaptureFile); |
255 | - if (!ok) { |
256 | - emit error(m_lastRequestId, QCameraImageCapture::ResourceError, |
257 | - QString("Could not save image to %1").arg(m_pendingCaptureFile)); |
258 | - m_pendingCaptureFile.clear(); |
259 | - m_service->updateCaptureReady(); |
260 | - return; |
261 | - } |
262 | - |
263 | - Q_EMIT imageSaved(m_lastRequestId, m_pendingCaptureFile); |
264 | - m_pendingCaptureFile.clear(); |
265 | - |
266 | - android_camera_start_preview(m_service->androidControl()); |
267 | + // Copy the metadata so that we can clear its container |
268 | + QVariantMap metadata; |
269 | + AalMetaDataWriterControl* metadataControl = m_service->metadataWriterControl(); |
270 | + Q_FOREACH(QString key, metadataControl->availableMetaData()) { |
271 | + metadata.insert(key, metadataControl->metaData(key)); |
272 | + } |
273 | + m_service->metadataWriterControl()->clearAllMetaData(); |
274 | + |
275 | + QString fileName = m_targetFileName; |
276 | + m_targetFileName.clear(); |
277 | + |
278 | + AalViewfinderSettingsControl* viewfinder = m_service->viewfinderControl(); |
279 | + QSize resolution = viewfinder->viewfinderParameter(QCameraViewfinderSettingsControl::Resolution).toSize(); |
280 | + |
281 | + // Restart the viewfinder and notify that the camera is ready to capture again |
282 | + if (m_service->androidControl()) { |
283 | + android_camera_start_preview(m_service->androidControl()); |
284 | + } |
285 | m_service->updateCaptureReady(); |
286 | + |
287 | + DiskWriteWatcher* watcher = new DiskWriteWatcher(this); |
288 | + QObject::connect(watcher, &QFutureWatcher<QString>::finished, this, &AalImageCaptureControl::onImageFileSaved); |
289 | + m_pendingSaveOperations.insert(watcher, m_lastRequestId); |
290 | + |
291 | + QFuture<SaveToDiskResult> future = QtConcurrent::run(&m_storageManager, &StorageManager::saveJpegImage, |
292 | + data, metadata, fileName, resolution, m_lastRequestId); |
293 | + watcher->setFuture(future); |
294 | +} |
295 | + |
296 | +void AalImageCaptureControl::onImageFileSaved() |
297 | +{ |
298 | + DiskWriteWatcher* watcher = static_cast<DiskWriteWatcher*>(sender()); |
299 | + |
300 | + if (m_pendingSaveOperations.contains(watcher)) { |
301 | + int requestID = m_pendingSaveOperations.take(watcher); |
302 | + |
303 | + SaveToDiskResult result = watcher->result(); |
304 | + delete watcher; |
305 | + |
306 | + if (result.success) { |
307 | + Q_EMIT imageSaved(requestID, result.fileName); |
308 | + } else { |
309 | + Q_EMIT error(requestID, QCameraImageCapture::ResourceError, result.errorMessage); |
310 | + } |
311 | + } |
312 | } |
313 | |
314 | === modified file 'src/aalimagecapturecontrol.h' |
315 | --- src/aalimagecapturecontrol.h 2016-01-11 15:10:38 +0000 |
316 | +++ src/aalimagecapturecontrol.h 2016-02-23 11:36:01 +0000 |
317 | @@ -20,7 +20,7 @@ |
318 | #include <QCameraImageCaptureControl> |
319 | #include <QSettings> |
320 | #include <QString> |
321 | -#include <QTemporaryFile> |
322 | +#include <QFutureWatcher> |
323 | #include <storagemanager.h> |
324 | |
325 | #include <stdint.h> |
326 | @@ -31,6 +31,8 @@ |
327 | class CameraControlListener; |
328 | class QMediaPlayer; |
329 | |
330 | +typedef QFutureWatcher<SaveToDiskResult> DiskWriteWatcher; |
331 | + |
332 | class AalImageCaptureControl : public QCameraImageCaptureControl |
333 | { |
334 | Q_OBJECT |
335 | @@ -55,13 +57,13 @@ |
336 | |
337 | public Q_SLOTS: |
338 | void init(CameraControl *control, CameraControlListener *listener); |
339 | - void onPreviewReady(); |
340 | + void onImageFileSaved(); |
341 | |
342 | private Q_SLOTS: |
343 | void shutter(); |
344 | + void saveJpeg(const QByteArray& data); |
345 | |
346 | private: |
347 | - void saveJpeg(void* data, uint32_t dataSize); |
348 | bool updateJpegMetadata(void* data, uint32_t dataSize, QTemporaryFile* destination); |
349 | |
350 | AalCameraService *m_service; |
351 | @@ -69,7 +71,7 @@ |
352 | int m_lastRequestId; |
353 | StorageManager m_storageManager; |
354 | bool m_ready; |
355 | - QString m_pendingCaptureFile; |
356 | + QString m_targetFileName; |
357 | bool m_captureCancelled; |
358 | float m_screenAspectRatio; |
359 | /// Maintains a list of highest priority aspect ratio to lowest, for the |
360 | @@ -78,6 +80,8 @@ |
361 | QString m_galleryPath; |
362 | QMediaPlayer *m_audioPlayer; |
363 | QSettings m_settings; |
364 | + |
365 | + QMap<DiskWriteWatcher*, int> m_pendingSaveOperations; |
366 | }; |
367 | |
368 | #endif |
369 | |
370 | === modified file 'src/storagemanager.cpp' |
371 | --- src/storagemanager.cpp 2014-09-10 19:48:00 +0000 |
372 | +++ src/storagemanager.cpp 2016-02-23 11:36:01 +0000 |
373 | @@ -15,12 +15,18 @@ |
374 | */ |
375 | |
376 | #include "storagemanager.h" |
377 | + |
378 | #include <QDateTime> |
379 | #include <QDebug> |
380 | #include <QDir> |
381 | #include <QFileInfo> |
382 | #include <QStandardPaths> |
383 | #include <QCoreApplication> |
384 | +#include <QBuffer> |
385 | +#include <QImageReader> |
386 | + |
387 | +#include <exiv2/exiv2.hpp> |
388 | +#include <cmath> |
389 | |
390 | const QLatin1String photoBase = QLatin1String("image"); |
391 | const QLatin1String videoBase = QLatin1String("video"); |
392 | @@ -28,7 +34,7 @@ |
393 | const QLatin1String videoExtension = QLatin1String("mp4"); |
394 | const QLatin1String dateFormat = QLatin1String("yyyyMMdd_HHmmsszzz"); |
395 | |
396 | -StorageManager::StorageManager() |
397 | +StorageManager::StorageManager(QObject* parent) : QObject(parent) |
398 | { |
399 | } |
400 | |
401 | @@ -87,3 +93,169 @@ |
402 | .arg(date) |
403 | .arg(extension); |
404 | } |
405 | + |
406 | +bool StorageManager::updateJpegMetadata(QByteArray data, QVariantMap metadata, QTemporaryFile* destination) |
407 | +{ |
408 | + if (data.isEmpty() || destination == 0) return false; |
409 | + |
410 | + Exiv2::Image::AutoPtr image; |
411 | + try { |
412 | + image = Exiv2::ImageFactory::open(static_cast<const Exiv2::byte*>((const unsigned char*)data.constData()), data.size()); |
413 | + if (!image.get()) { |
414 | + return false; |
415 | + } |
416 | + } catch(const Exiv2::AnyError&) { |
417 | + return false; |
418 | + } |
419 | + |
420 | + try { |
421 | + image->readMetadata(); |
422 | + Exiv2::ExifData ed = image->exifData(); |
423 | + const QString now = QDateTime::currentDateTime().toString("yyyy:MM:dd HH:mm:ss"); |
424 | + ed["Exif.Photo.DateTimeOriginal"].setValue(now.toStdString()); |
425 | + ed["Exif.Photo.DateTimeDigitized"].setValue(now.toStdString()); |
426 | + |
427 | + if (metadata.contains("GPSLatitude") && |
428 | + metadata.contains("GPSLongitude") && |
429 | + metadata.contains("GPSTimeStamp")) { |
430 | + |
431 | + // Write all GPS metadata according to version 2.2 of the EXIF spec, |
432 | + // which is what Android did. See: http://www.exiv2.org/Exif2-2.PDF |
433 | + const char version[4] = {2, 2, 0, 0}; |
434 | + Exiv2::DataValue versionValue(Exiv2::unsignedByte); |
435 | + versionValue.read((const Exiv2::byte*)version, 4); |
436 | + ed.add(Exiv2::ExifKey("Exif.GPSInfo.GPSVersionID"), &versionValue); |
437 | + |
438 | + // According to the spec, the GPS processing method is a buffer of type Undefined, which |
439 | + // does not need to be zero terminated. It should be prepended by an 8 byte, zero padded |
440 | + // string specifying the encoding. |
441 | + const char methodHeader[8] = {'A', 'S', 'C', 'I', 'I', 0, 0, 0}; |
442 | + QByteArray method = metadata.value("GPSProcessingMethod").toString().toLatin1(); |
443 | + method.prepend(methodHeader, 8); |
444 | + Exiv2::DataValue methodValue(Exiv2::undefined); |
445 | + methodValue.read((const Exiv2::byte*)method.constData(), method.size()); |
446 | + ed.add(Exiv2::ExifKey("Exif.GPSInfo.GPSProcessingMethod"), &methodValue); |
447 | + |
448 | + double latitude = metadata.value("GPSLatitude").toDouble(); |
449 | + ed["Exif.GPSInfo.GPSLatitude"] = decimalToExifRational(latitude).toStdString(); |
450 | + ed["Exif.GPSInfo.GPSLatitudeRef"] = (latitude < 0 ) ? "S" : "N"; |
451 | + |
452 | + double longitude = metadata.value("GPSLongitude").toDouble(); |
453 | + ed["Exif.GPSInfo.GPSLongitude"] = decimalToExifRational(longitude).toStdString(); |
454 | + ed["Exif.GPSInfo.GPSLongitudeRef"] = (longitude < 0 ) ? "W" : "E"; |
455 | + |
456 | + if (metadata.contains("GPSAltitude")) { |
457 | + // Assume altitude precision to the meter |
458 | + unsigned int altitude = floor(metadata.value("GPSAltitude").toDouble()); |
459 | + Exiv2::URationalValue::AutoPtr altitudeValue(new Exiv2::URationalValue); |
460 | + altitudeValue->value_.push_back(std::make_pair(altitude,1)); |
461 | + ed.add(Exiv2::ExifKey("Exif.GPSInfo.GPSAltitude"), altitudeValue.get()); |
462 | + |
463 | + // Byte field of lenght 1. Value of 0 means the reference is sea level. |
464 | + const char reference = 0; |
465 | + Exiv2::DataValue referenceValue(Exiv2::unsignedByte); |
466 | + referenceValue.read((const Exiv2::byte*) &reference, 1); |
467 | + ed.add(Exiv2::ExifKey("Exif.GPSInfo.GPSAltitudeRef"), &referenceValue); |
468 | + } |
469 | + |
470 | + QDateTime stamp = metadata.value("GPSTimeStamp").toDateTime(); |
471 | + ed["Exif.GPSInfo.GPSTimeStamp"] = stamp.toString("HH/1 mm/1 ss/1").toStdString(); |
472 | + ed["Exif.GPSInfo.GPSDateStamp"] = stamp.toString("yyyy:MM:dd").toStdString(); |
473 | + } |
474 | + |
475 | + image->setExifData(ed); |
476 | + image->writeMetadata(); |
477 | + } catch(const Exiv2::AnyError&) { |
478 | + return false; |
479 | + } |
480 | + |
481 | + if (!destination->open()) { |
482 | + return false; |
483 | + } |
484 | + |
485 | + try { |
486 | + Exiv2::BasicIo& io = image->io(); |
487 | + char* modifiedMetadata = reinterpret_cast<char*>(io.mmap()); |
488 | + const long size = io.size(); |
489 | + const qint64 writtenSize = destination->write(modifiedMetadata, size); |
490 | + io.munmap(); |
491 | + destination->close(); |
492 | + return (writtenSize == size); |
493 | + |
494 | + } catch(const Exiv2::AnyError&) { |
495 | + destination->close(); |
496 | + return false; |
497 | + } |
498 | +} |
499 | + |
500 | +SaveToDiskResult StorageManager::saveJpegImage(QByteArray data, QVariantMap metadata, QString fileName, |
501 | + QSize previewResolution, int captureID) |
502 | +{ |
503 | + SaveToDiskResult result; |
504 | + |
505 | + QString captureFile; |
506 | + QFileInfo fi(fileName); |
507 | + if (fileName.isEmpty() || fi.isDir()) { |
508 | + captureFile = nextPhotoFileName(fileName); |
509 | + } else { |
510 | + captureFile = fileName; |
511 | + } |
512 | + result.fileName = captureFile; |
513 | + |
514 | + bool diskOk = checkDirectory(captureFile); |
515 | + if (!diskOk) { |
516 | + result.errorMessage = QString("Won't be able to save file %1 to disk").arg(captureFile); |
517 | + return result; |
518 | + } |
519 | + |
520 | + QBuffer buffer(&data); |
521 | + QImageReader reader(&buffer, "jpg"); |
522 | + |
523 | + QSize scaledSize = reader.size(); // fast, as it does not decode the JPEG |
524 | + scaledSize.scale(previewResolution, Qt::KeepAspectRatio); |
525 | + reader.setScaledSize(scaledSize); |
526 | + reader.setQuality(25); |
527 | + QImage image = reader.read(); |
528 | + Q_EMIT previewReady(captureID, image); |
529 | + |
530 | + QTemporaryFile file; |
531 | + if (!updateJpegMetadata(data, metadata, &file)) { |
532 | + qWarning() << "Failed to update EXIF timestamps. Picture will be saved as UTC timezone."; |
533 | + if (!file.open()) { |
534 | + result.errorMessage = QString("Could not open temprary file %1").arg(file.fileName()); |
535 | + return result; |
536 | + } |
537 | + |
538 | + const qint64 writtenSize = file.write(data); |
539 | + file.close(); |
540 | + if (writtenSize != data.size()) { |
541 | + result.errorMessage = QString("Could not write file %1").arg(fileName); |
542 | + return result; |
543 | + } |
544 | + } |
545 | + |
546 | + QFile finalFile(file.fileName()); |
547 | + bool ok = finalFile.rename(captureFile); |
548 | + if (!ok) { |
549 | + result.errorMessage = QString("Could not save image to %1").arg(fileName); |
550 | + return result; |
551 | + } |
552 | + |
553 | + result.success = true; |
554 | + return result; |
555 | +} |
556 | + |
557 | +QString StorageManager::decimalToExifRational(double decimal) |
558 | +{ |
559 | + decimal = fabs(decimal); |
560 | + unsigned int degrees = floor(decimal); |
561 | + unsigned int minutes = floor((decimal - degrees) * 60); |
562 | + double seconds = (decimal - degrees - minutes / 60) * 3600; |
563 | + seconds = floor(seconds * 100); |
564 | + |
565 | + return QString("%1/1 %2/1 %3/100").arg(degrees).arg(minutes).arg(seconds); |
566 | +} |
567 | + |
568 | +SaveToDiskResult::SaveToDiskResult() : success(false) |
569 | +{ |
570 | +} |
571 | |
572 | === modified file 'src/storagemanager.h' |
573 | --- src/storagemanager.h 2014-09-10 19:48:00 +0000 |
574 | +++ src/storagemanager.h 2016-02-23 11:36:01 +0000 |
575 | @@ -18,19 +18,43 @@ |
576 | #define STORAGEMANAGER_H |
577 | |
578 | #include <QString> |
579 | - |
580 | -class StorageManager |
581 | -{ |
582 | -public: |
583 | - StorageManager(); |
584 | +#include <QVariantMap> |
585 | +#include <QByteArray> |
586 | +#include <QTemporaryFile> |
587 | +#include <QImage> |
588 | + |
589 | +class SaveToDiskResult |
590 | +{ |
591 | +public: |
592 | + SaveToDiskResult(); |
593 | + bool success; |
594 | + QString fileName; |
595 | + QString errorMessage; |
596 | +}; |
597 | + |
598 | +class StorageManager : public QObject |
599 | +{ |
600 | + Q_OBJECT |
601 | + |
602 | +public: |
603 | + explicit StorageManager(QObject* parent = 0); |
604 | |
605 | QString nextPhotoFileName(const QString &directoy = QString()); |
606 | QString nextVideoFileName(const QString &directoy = QString()); |
607 | |
608 | bool checkDirectory(const QString &path) const; |
609 | |
610 | + SaveToDiskResult saveJpegImage(QByteArray data, QVariantMap metadata, |
611 | + QString fileName, QSize previewResolution, |
612 | + int captureID); |
613 | + |
614 | +Q_SIGNALS: |
615 | + void previewReady(int captureID, QImage image); |
616 | + |
617 | private: |
618 | QString fileNameGenerator(const QString &base, const QString &extension); |
619 | + bool updateJpegMetadata(QByteArray data, QVariantMap metadata, QTemporaryFile* destination); |
620 | + QString decimalToExifRational(double decimal); |
621 | |
622 | QString m_directory; |
623 | }; |
624 | |
625 | === modified file 'unittests/aalcamerafocuscontrol/aalcamerafocuscontrol.pro' |
626 | --- unittests/aalcamerafocuscontrol/aalcamerafocuscontrol.pro 2014-01-16 14:20:08 +0000 |
627 | +++ unittests/aalcamerafocuscontrol/aalcamerafocuscontrol.pro 2016-02-23 11:36:01 +0000 |
628 | @@ -10,10 +10,12 @@ |
629 | |
630 | HEADERS += ../../src/aalcamerafocuscontrol.h \ |
631 | ../../src/aalcameraservice.h \ |
632 | - ../../src/aalimagecapturecontrol.h |
633 | + ../../src/aalimagecapturecontrol.h \ |
634 | + ../../src/storagemanager.h |
635 | |
636 | SOURCES += tst_aalcamerafocuscontrol.cpp \ |
637 | ../../src/aalcamerafocuscontrol.cpp \ |
638 | + storagemanager.cpp \ |
639 | aalcameraservice.cpp \ |
640 | aalimagecapturecontrol.cpp |
641 | |
642 | |
643 | === modified file 'unittests/aalcamerafocuscontrol/aalimagecapturecontrol.cpp' |
644 | --- unittests/aalcamerafocuscontrol/aalimagecapturecontrol.cpp 2013-06-05 16:11:12 +0000 |
645 | +++ unittests/aalcamerafocuscontrol/aalimagecapturecontrol.cpp 2016-02-23 11:36:01 +0000 |
646 | @@ -19,10 +19,6 @@ |
647 | #include <hybris/camera/camera_compatibility_layer.h> |
648 | #include <hybris/camera/camera_compatibility_layer_capabilities.h> |
649 | |
650 | -StorageManager::StorageManager() |
651 | -{ |
652 | -} |
653 | - |
654 | AalImageCaptureControl::AalImageCaptureControl(AalCameraService *service, QObject *parent) |
655 | : QCameraImageCaptureControl(parent) |
656 | { |
657 | @@ -54,10 +50,6 @@ |
658 | Q_UNUSED(listener); |
659 | } |
660 | |
661 | -void AalImageCaptureControl::onPreviewReady() |
662 | -{ |
663 | -} |
664 | - |
665 | void AalImageCaptureControl::setReady(bool ready) |
666 | { |
667 | Q_UNUSED(ready); |
668 | @@ -66,3 +58,13 @@ |
669 | void AalImageCaptureControl::shutter() |
670 | { |
671 | } |
672 | + |
673 | +void AalImageCaptureControl::onImageFileSaved() |
674 | +{ |
675 | +} |
676 | + |
677 | +void AalImageCaptureControl::saveJpeg(const QByteArray& data) |
678 | +{ |
679 | + Q_UNUSED(data); |
680 | +} |
681 | + |
682 | |
683 | === added file 'unittests/aalcamerafocuscontrol/storagemanager.cpp' |
684 | --- unittests/aalcamerafocuscontrol/storagemanager.cpp 1970-01-01 00:00:00 +0000 |
685 | +++ unittests/aalcamerafocuscontrol/storagemanager.cpp 2016-02-23 11:36:01 +0000 |
686 | @@ -0,0 +1,76 @@ |
687 | +/* |
688 | + * Copyright (C) 2016 Canonical, Ltd. |
689 | + * |
690 | + * This program is free software; you can redistribute it and/or modify |
691 | + * it under the terms of the GNU Lesser General Public License as published by |
692 | + * the Free Software Foundation; version 3. |
693 | + * |
694 | + * This program is distributed in the hope that it will be useful, |
695 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
696 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
697 | + * GNU Lesser General Public License for more details. |
698 | + * |
699 | + * You should have received a copy of the GNU Lesser General Public License |
700 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
701 | + */ |
702 | + |
703 | +#include "storagemanager.h" |
704 | + |
705 | +StorageManager::StorageManager(QObject* parent) : QObject(parent) |
706 | +{ |
707 | +} |
708 | + |
709 | +QString StorageManager::nextPhotoFileName(const QString &directoy) |
710 | +{ |
711 | + Q_UNUSED(directoy); |
712 | + return QString(); |
713 | +} |
714 | + |
715 | +QString StorageManager::nextVideoFileName(const QString &directoy) |
716 | +{ |
717 | + Q_UNUSED(directoy); |
718 | + return QString(); |
719 | +} |
720 | + |
721 | +bool StorageManager::checkDirectory(const QString &path) const |
722 | +{ |
723 | + Q_UNUSED(path); |
724 | + return true; |
725 | +} |
726 | + |
727 | +QString StorageManager::fileNameGenerator(const QString &base, const QString& extension) |
728 | +{ |
729 | + Q_UNUSED(base); |
730 | + Q_UNUSED(extension); |
731 | + return QString(); |
732 | +} |
733 | + |
734 | +bool StorageManager::updateJpegMetadata(QByteArray data, QVariantMap metadata, QTemporaryFile* destination) |
735 | +{ |
736 | + Q_UNUSED(data); |
737 | + Q_UNUSED(metadata); |
738 | + Q_UNUSED(destination); |
739 | + |
740 | + return true; |
741 | +} |
742 | + |
743 | +SaveToDiskResult StorageManager::saveJpegImage(QByteArray data, QVariantMap metadata, |
744 | + QString fileName, QSize previewResolution, int captureID) |
745 | +{ |
746 | + Q_UNUSED(data); |
747 | + Q_UNUSED(metadata); |
748 | + Q_UNUSED(fileName); |
749 | + Q_UNUSED(captureID); |
750 | + Q_UNUSED(previewResolution); |
751 | + return SaveToDiskResult(); |
752 | +} |
753 | + |
754 | +QString StorageManager::decimalToExifRational(double decimal) |
755 | +{ |
756 | + Q_UNUSED(decimal); |
757 | + return QString(); |
758 | +} |
759 | + |
760 | +SaveToDiskResult::SaveToDiskResult() : success(false) |
761 | +{ |
762 | +} |
763 | |
764 | === modified file 'unittests/aalcamerafocuscontrol/tst_aalcamerafocuscontrol.cpp' |
765 | --- unittests/aalcamerafocuscontrol/tst_aalcamerafocuscontrol.cpp 2015-04-08 12:57:01 +0000 |
766 | +++ unittests/aalcamerafocuscontrol/tst_aalcamerafocuscontrol.cpp 2016-02-23 11:36:01 +0000 |
767 | @@ -127,8 +127,8 @@ |
768 | QTest::addColumn<int>("bottom"); |
769 | |
770 | QTest::newRow("center") << (qreal)0.5 << (qreal)0.5 << -100 << 100 << -100 << 100; |
771 | - QTest::newRow("topLeft") << (qreal)0.0 << (qreal)1.0 << -1000 << -800 << -1000 << -800; |
772 | - QTest::newRow("bottomRight") << (qreal)1.0 << (qreal)0.0 << 800 << 1000 << 800 << 1000; |
773 | + QTest::newRow("topLeft") << (qreal)0.0 << (qreal)1.0 << -1000 << -800 << 800 << 1000; |
774 | + QTest::newRow("bottomRight") << (qreal)1.0 << (qreal)0.0 << 800 << 1000 << -1000 << -800; |
775 | } |
776 | |
777 | void tst_AalCameraFocusControl::point2Region() |
778 | |
779 | === removed directory 'unittests/aalimagecapturecontrol' |
780 | === removed file 'unittests/aalimagecapturecontrol/aalcameraservice.cpp' |
781 | --- unittests/aalimagecapturecontrol/aalcameraservice.cpp 2015-12-07 15:16:51 +0000 |
782 | +++ unittests/aalimagecapturecontrol/aalcameraservice.cpp 1970-01-01 00:00:00 +0000 |
783 | @@ -1,99 +0,0 @@ |
784 | -/* |
785 | - * Copyright (C) 2013 Canonical, Ltd. |
786 | - * |
787 | - * This program is free software; you can redistribute it and/or modify |
788 | - * it under the terms of the GNU Lesser General Public License as published by |
789 | - * the Free Software Foundation; version 3. |
790 | - * |
791 | - * This program is distributed in the hope that it will be useful, |
792 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
793 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
794 | - * GNU Lesser General Public License for more details. |
795 | - * |
796 | - * You should have received a copy of the GNU Lesser General Public License |
797 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
798 | - */ |
799 | - |
800 | -#include "aalcameraservice.h" |
801 | - |
802 | -AalCameraService *AalCameraService::m_service = 0; |
803 | - |
804 | -AalCameraService::AalCameraService(QObject *parent) : |
805 | - QMediaService(parent), |
806 | - m_androidControl(0), |
807 | - m_androidListener(0) |
808 | -{ |
809 | -} |
810 | - |
811 | -AalCameraService::~AalCameraService() |
812 | -{ |
813 | -} |
814 | - |
815 | -QMediaControl *AalCameraService::requestControl(const char *name) |
816 | -{ |
817 | - Q_UNUSED(name); |
818 | - return 0; |
819 | -} |
820 | - |
821 | -void AalCameraService::releaseControl(QMediaControl *control) |
822 | -{ |
823 | - Q_UNUSED(control); |
824 | -} |
825 | - |
826 | -CameraControl *AalCameraService::androidControl() |
827 | -{ |
828 | - return m_androidControl; |
829 | -} |
830 | - |
831 | -bool AalCameraService::connectCamera() |
832 | -{ |
833 | - return true; |
834 | -} |
835 | - |
836 | -void AalCameraService::disconnectCamera() |
837 | -{ |
838 | -} |
839 | - |
840 | -void AalCameraService::startPreview() |
841 | -{ |
842 | -} |
843 | - |
844 | -void AalCameraService::stopPreview() |
845 | -{ |
846 | -} |
847 | - |
848 | -bool AalCameraService::isPreviewStarted() const |
849 | -{ |
850 | - return true; |
851 | -} |
852 | - |
853 | -void AalCameraService::onApplicationStateChanged() |
854 | -{ |
855 | -} |
856 | - |
857 | -void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener) |
858 | -{ |
859 | - Q_UNUSED(camControl); |
860 | - Q_UNUSED(listener); |
861 | -} |
862 | - |
863 | -bool AalCameraService::isCameraActive() const |
864 | -{ |
865 | - return true; |
866 | -} |
867 | - |
868 | -bool AalCameraService::isBackCameraUsed() const |
869 | -{ |
870 | - return true; |
871 | -} |
872 | - |
873 | -void AalCameraService::updateCaptureReady() |
874 | -{ |
875 | -} |
876 | - |
877 | -QSize AalCameraService::selectSizeWithAspectRatio(const QList<QSize> &sizes, float targetAspectRatio) const |
878 | -{ |
879 | - Q_UNUSED(sizes); |
880 | - Q_UNUSED(targetAspectRatio); |
881 | - return QSize(); |
882 | -} |
883 | |
884 | === removed file 'unittests/aalimagecapturecontrol/aalimagecapturecontrol.pro' |
885 | --- unittests/aalimagecapturecontrol/aalimagecapturecontrol.pro 2014-09-23 18:12:45 +0000 |
886 | +++ unittests/aalimagecapturecontrol/aalimagecapturecontrol.pro 1970-01-01 00:00:00 +0000 |
887 | @@ -1,31 +0,0 @@ |
888 | -include(../../coverage.pri) |
889 | - |
890 | -TARGET = tst_aalimagecapturecontrol |
891 | - |
892 | -QT += testlib multimedia opengl |
893 | - |
894 | -LIBS += -L../mocks/aal -laal |
895 | -INCLUDEPATH += ../../src |
896 | -INCLUDEPATH += ../mocks/aal |
897 | - |
898 | -CONFIG += link_pkgconfig |
899 | -PKGCONFIG += exiv2 |
900 | - |
901 | -HEADERS += ../../src/aalimagecapturecontrol.h \ |
902 | - ../../src/aalcameraservice.h \ |
903 | - ../../src/aalimageencodercontrol.h \ |
904 | - ../../src/aalmetadatawritercontrol.h \ |
905 | - ../../src/aalvideorenderercontrol.h \ |
906 | - ../../src/storagemanager.h |
907 | - |
908 | -SOURCES += tst_aalimagecapturecontrol.cpp \ |
909 | - ../../src/aalimagecapturecontrol.cpp \ |
910 | - aalcameraservice.cpp \ |
911 | - aalimageencodercontrol.cpp \ |
912 | - ../stubs/aalmetadatawritercontrol_stub.cpp \ |
913 | - aalvideorenderercontrol.cpp \ |
914 | - storagemanager.cpp |
915 | - |
916 | -check.depends = $${TARGET} |
917 | -check.commands = ./$${TARGET} |
918 | -QMAKE_EXTRA_TARGETS += check |
919 | |
920 | === removed file 'unittests/aalimagecapturecontrol/aalimageencodercontrol.cpp' |
921 | --- unittests/aalimagecapturecontrol/aalimageencodercontrol.cpp 2015-10-14 21:22:46 +0000 |
922 | +++ unittests/aalimagecapturecontrol/aalimageencodercontrol.cpp 1970-01-01 00:00:00 +0000 |
923 | @@ -1,125 +0,0 @@ |
924 | -/* |
925 | - * Copyright (C) 2013-2014 Canonical, Ltd. |
926 | - * |
927 | - * This program is free software; you can redistribute it and/or modify |
928 | - * it under the terms of the GNU Lesser General Public License as published by |
929 | - * the Free Software Foundation; version 3. |
930 | - * |
931 | - * This program is distributed in the hope that it will be useful, |
932 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
933 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
934 | - * GNU Lesser General Public License for more details. |
935 | - * |
936 | - * You should have received a copy of the GNU Lesser General Public License |
937 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
938 | - */ |
939 | - |
940 | -#include <QImageEncoderControl> |
941 | -#include <QList> |
942 | -#include <QString> |
943 | -#include <QStringList> |
944 | - |
945 | -#include <QDebug> |
946 | - |
947 | -#include "aalimageencodercontrol.h" |
948 | - |
949 | -AalImageEncoderControl::AalImageEncoderControl(AalCameraService *service, QObject *parent) |
950 | - : QImageEncoderControl(parent), |
951 | - m_service(service), |
952 | - m_currentSize() |
953 | -{ |
954 | -} |
955 | - |
956 | -AalImageEncoderControl::~AalImageEncoderControl() |
957 | -{ |
958 | -} |
959 | - |
960 | -QString AalImageEncoderControl::imageCodecDescription(const QString &codec) const |
961 | -{ |
962 | - Q_UNUSED(codec); |
963 | - return QString(); |
964 | -} |
965 | - |
966 | -QImageEncoderSettings AalImageEncoderControl::imageSettings() const |
967 | -{ |
968 | - return QImageEncoderSettings(); |
969 | -} |
970 | - |
971 | -void AalImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings) |
972 | -{ |
973 | - Q_UNUSED(settings); |
974 | -} |
975 | - |
976 | -QStringList AalImageEncoderControl::supportedImageCodecs() const |
977 | -{ |
978 | - return QStringList(); |
979 | -} |
980 | - |
981 | -QList<QSize> AalImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const |
982 | -{ |
983 | - Q_UNUSED(settings); |
984 | - Q_UNUSED(continuous); |
985 | - |
986 | - return QList<QSize>(); |
987 | -} |
988 | - |
989 | -QList<QSize> AalImageEncoderControl::supportedThumbnailResolutions(const QImageEncoderSettings &settings, bool *continuous) const |
990 | -{ |
991 | - Q_UNUSED(settings); |
992 | - Q_UNUSED(continuous); |
993 | - |
994 | - return QList<QSize>(); |
995 | -} |
996 | - |
997 | -void AalImageEncoderControl::init(CameraControl *control) |
998 | -{ |
999 | - Q_UNUSED(control); |
1000 | -} |
1001 | - |
1002 | -bool AalImageEncoderControl::setSize(const QSize &size) |
1003 | -{ |
1004 | - Q_UNUSED(size); |
1005 | - return true; |
1006 | -} |
1007 | - |
1008 | -void AalImageEncoderControl::resetAllSettings() |
1009 | -{ |
1010 | -} |
1011 | - |
1012 | -void AalImageEncoderControl::getPictureSizeCb(void *ctx, int width, int height) |
1013 | -{ |
1014 | - Q_UNUSED(ctx); |
1015 | - Q_UNUSED(width); |
1016 | - Q_UNUSED(height); |
1017 | -} |
1018 | - |
1019 | -void AalImageEncoderControl::getPictureSize(int width, int height) |
1020 | -{ |
1021 | - Q_UNUSED(width); |
1022 | - Q_UNUSED(height); |
1023 | -} |
1024 | - |
1025 | -void AalImageEncoderControl::getThumbnailSizeCb(void *ctx, int width, int height) |
1026 | -{ |
1027 | - Q_UNUSED(ctx); |
1028 | - Q_UNUSED(width); |
1029 | - Q_UNUSED(height); |
1030 | -} |
1031 | - |
1032 | -void AalImageEncoderControl::getThumbnailSize(int width, int height) |
1033 | -{ |
1034 | - Q_UNUSED(width); |
1035 | - Q_UNUSED(height); |
1036 | -} |
1037 | - |
1038 | -QMultimedia::EncodingQuality AalImageEncoderControl::jpegQualityToQtEncodingQuality(int jpegQuality) |
1039 | -{ |
1040 | - Q_UNUSED(jpegQuality) |
1041 | - return QMultimedia::NormalQuality; |
1042 | -} |
1043 | - |
1044 | -int AalImageEncoderControl::qtEncodingQualityToJpegQuality(QMultimedia::EncodingQuality quality) |
1045 | -{ |
1046 | - Q_UNUSED(quality) |
1047 | - return 100; |
1048 | -} |
1049 | |
1050 | === removed file 'unittests/aalimagecapturecontrol/aalvideorenderercontrol.cpp' |
1051 | --- unittests/aalimagecapturecontrol/aalvideorenderercontrol.cpp 2015-12-07 15:16:51 +0000 |
1052 | +++ unittests/aalimagecapturecontrol/aalvideorenderercontrol.cpp 1970-01-01 00:00:00 +0000 |
1053 | @@ -1,84 +0,0 @@ |
1054 | -/* |
1055 | - * Copyright (C) 2013 Canonical, Ltd. |
1056 | - * |
1057 | - * This program is free software; you can redistribute it and/or modify |
1058 | - * it under the terms of the GNU Lesser General Public License as published by |
1059 | - * the Free Software Foundation; version 3. |
1060 | - * |
1061 | - * This program is distributed in the hope that it will be useful, |
1062 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1063 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1064 | - * GNU Lesser General Public License for more details. |
1065 | - * |
1066 | - * You should have received a copy of the GNU Lesser General Public License |
1067 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1068 | - */ |
1069 | - |
1070 | -#include "aalvideorenderercontrol.h" |
1071 | -#include "aalcameraservice.h" |
1072 | - |
1073 | - |
1074 | -AalVideoRendererControl::AalVideoRendererControl(AalCameraService *service, QObject *parent) |
1075 | - : QVideoRendererControl(parent) |
1076 | - , m_surface(0), |
1077 | - m_service(service), |
1078 | - m_viewFinderRunning(false), |
1079 | - m_textureId(0) |
1080 | -{ |
1081 | -} |
1082 | - |
1083 | -AalVideoRendererControl::~AalVideoRendererControl() |
1084 | -{ |
1085 | -} |
1086 | - |
1087 | -QAbstractVideoSurface *AalVideoRendererControl::surface() const |
1088 | -{ |
1089 | - return m_surface; |
1090 | -} |
1091 | - |
1092 | -void AalVideoRendererControl::setSurface(QAbstractVideoSurface *surface) |
1093 | -{ |
1094 | - Q_UNUSED(surface); |
1095 | -} |
1096 | - |
1097 | -void AalVideoRendererControl::init(CameraControl *control, CameraControlListener *listener) |
1098 | -{ |
1099 | - Q_UNUSED(control); |
1100 | - Q_UNUSED(listener); |
1101 | -} |
1102 | - |
1103 | -void AalVideoRendererControl::startPreview() |
1104 | -{ |
1105 | -} |
1106 | - |
1107 | -void AalVideoRendererControl::stopPreview() |
1108 | -{ |
1109 | -} |
1110 | - |
1111 | -bool AalVideoRendererControl::isPreviewStarted() const |
1112 | -{ |
1113 | - return true; |
1114 | -} |
1115 | - |
1116 | -void AalVideoRendererControl::updateViewfinderFrame() |
1117 | -{ |
1118 | -} |
1119 | - |
1120 | -void AalVideoRendererControl::onTextureCreated(unsigned int textureID) |
1121 | -{ |
1122 | - Q_UNUSED(textureID); |
1123 | -} |
1124 | - |
1125 | -void AalVideoRendererControl::onSnapshotTaken(QImage snapshotImage) |
1126 | -{ |
1127 | - Q_UNUSED(snapshotImage); |
1128 | -} |
1129 | - |
1130 | -const QImage &AalVideoRendererControl::preview() const |
1131 | -{ |
1132 | - return m_preview; |
1133 | -} |
1134 | - |
1135 | -void AalVideoRendererControl::createPreview() |
1136 | -{ |
1137 | -} |
1138 | |
1139 | === removed file 'unittests/aalimagecapturecontrol/storagemanager.cpp' |
1140 | --- unittests/aalimagecapturecontrol/storagemanager.cpp 2014-09-10 19:48:00 +0000 |
1141 | +++ unittests/aalimagecapturecontrol/storagemanager.cpp 1970-01-01 00:00:00 +0000 |
1142 | @@ -1,50 +0,0 @@ |
1143 | -/* |
1144 | - * Copyright (C) 2013 Canonical, Ltd. |
1145 | - * |
1146 | - * This program is free software; you can redistribute it and/or modify |
1147 | - * it under the terms of the GNU Lesser General Public License as published by |
1148 | - * the Free Software Foundation; version 3. |
1149 | - * |
1150 | - * This program is distributed in the hope that it will be useful, |
1151 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1152 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1153 | - * GNU Lesser General Public License for more details. |
1154 | - * |
1155 | - * You should have received a copy of the GNU Lesser General Public License |
1156 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1157 | - */ |
1158 | - |
1159 | -#include <QDebug> |
1160 | -#include <QString> |
1161 | - |
1162 | -#include "storagemanager.h" |
1163 | - |
1164 | -StorageManager::StorageManager() |
1165 | -{ |
1166 | -} |
1167 | - |
1168 | -QString StorageManager::nextPhotoFileName(const QString &directory) |
1169 | -{ |
1170 | - Q_UNUSED(directory); |
1171 | - return QString(); |
1172 | -} |
1173 | - |
1174 | -QString StorageManager::nextVideoFileName(const QString &directory) |
1175 | -{ |
1176 | - Q_UNUSED(directory); |
1177 | - return QString(); |
1178 | -} |
1179 | - |
1180 | -bool StorageManager::checkDirectory(const QString &path) const |
1181 | -{ |
1182 | - Q_UNUSED(path); |
1183 | - return true; |
1184 | -} |
1185 | - |
1186 | -QString StorageManager::fileNameGenerator(const QString &base, |
1187 | - const QString& extension) |
1188 | -{ |
1189 | - Q_UNUSED(base); |
1190 | - Q_UNUSED(extension); |
1191 | - return QString(); |
1192 | -} |
1193 | |
1194 | === removed file 'unittests/aalimagecapturecontrol/tst_aalimagecapturecontrol.cpp' |
1195 | --- unittests/aalimagecapturecontrol/tst_aalimagecapturecontrol.cpp 2015-10-14 21:22:46 +0000 |
1196 | +++ unittests/aalimagecapturecontrol/tst_aalimagecapturecontrol.cpp 1970-01-01 00:00:00 +0000 |
1197 | @@ -1,74 +0,0 @@ |
1198 | -/* |
1199 | - * Copyright (C) 2013 Canonical, Ltd. |
1200 | - * |
1201 | - * This program is free software; you can redistribute it and/or modify |
1202 | - * it under the terms of the GNU Lesser General Public License as published by |
1203 | - * the Free Software Foundation; version 3. |
1204 | - * |
1205 | - * This program is distributed in the hope that it will be useful, |
1206 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1207 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1208 | - * GNU Lesser General Public License for more details. |
1209 | - * |
1210 | - * You should have received a copy of the GNU Lesser General Public License |
1211 | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1212 | - */ |
1213 | - |
1214 | -#include <QtTest/QtTest> |
1215 | -#include <cmath> |
1216 | - |
1217 | -#include "aalcameraservice.h" |
1218 | -#include "data_validjpeg.h" |
1219 | -#include "data_noexifjpeg.h" |
1220 | - |
1221 | -#define private public |
1222 | -#include "aalimagecapturecontrol.h" |
1223 | - |
1224 | -class tst_AalImageCaptureControl : public QObject |
1225 | -{ |
1226 | - Q_OBJECT |
1227 | -private slots: |
1228 | - void initTestCase(); |
1229 | - void cleanupTestCase(); |
1230 | - |
1231 | - void updateEXIF(); |
1232 | - |
1233 | -private: |
1234 | - AalImageCaptureControl *m_icControl; |
1235 | - AalCameraService *m_service; |
1236 | - |
1237 | - friend class AalImageCaptureControl; |
1238 | -}; |
1239 | - |
1240 | -void tst_AalImageCaptureControl::initTestCase() |
1241 | -{ |
1242 | - m_service = new AalCameraService(); |
1243 | - m_icControl = new AalImageCaptureControl(m_service); |
1244 | -} |
1245 | - |
1246 | -void tst_AalImageCaptureControl::cleanupTestCase() |
1247 | -{ |
1248 | - delete m_icControl; |
1249 | - delete m_service; |
1250 | -} |
1251 | - |
1252 | -void tst_AalImageCaptureControl::updateEXIF() |
1253 | -{ |
1254 | - bool result; |
1255 | - QTemporaryFile tmp; |
1256 | - char *invalidJPEG = "INVALID_IMAGE"; |
1257 | - result = m_icControl->updateJpegMetadata(0, 0, &tmp); |
1258 | - QCOMPARE(result, false); |
1259 | - result = m_icControl->updateJpegMetadata(invalidJPEG, strlen(invalidJPEG), 0); |
1260 | - QCOMPARE(result, false); |
1261 | - result = m_icControl->updateJpegMetadata(invalidJPEG, strlen(invalidJPEG), &tmp); |
1262 | - QCOMPARE(result, false); |
1263 | - result = m_icControl->updateJpegMetadata(data_validjpeg, data_validjpeg_len, &tmp); |
1264 | - QCOMPARE(result, true); |
1265 | - result = m_icControl->updateJpegMetadata(data_noexifjpeg, data_noexifjpeg_len, &tmp); |
1266 | - QCOMPARE(result, true); |
1267 | -} |
1268 | - |
1269 | -QTEST_GUILESS_MAIN(tst_AalImageCaptureControl) |
1270 | - |
1271 | -#include "tst_aalimagecapturecontrol.moc" |
1272 | |
1273 | === renamed file 'unittests/aalimagecapturecontrol/data_noexifjpeg.h' => 'unittests/storagemanager/data_noexifjpeg.h' |
1274 | === renamed file 'unittests/aalimagecapturecontrol/data_validjpeg.h' => 'unittests/storagemanager/data_validjpeg.h' |
1275 | === modified file 'unittests/storagemanager/storagemanager.pro' |
1276 | --- unittests/storagemanager/storagemanager.pro 2013-06-13 19:13:27 +0000 |
1277 | +++ unittests/storagemanager/storagemanager.pro 2016-02-23 11:36:01 +0000 |
1278 | @@ -4,6 +4,11 @@ |
1279 | |
1280 | QT += testlib |
1281 | |
1282 | +CONFIG += link_pkgconfig |
1283 | +PKGCONFIG += exiv2 |
1284 | + |
1285 | +HEADERS += ../../src/storagemanager.h |
1286 | + |
1287 | SOURCES += tst_storagemanager.cpp \ |
1288 | ../../src/storagemanager.cpp |
1289 | |
1290 | |
1291 | === modified file 'unittests/storagemanager/tst_storagemanager.cpp' |
1292 | --- unittests/storagemanager/tst_storagemanager.cpp 2014-09-10 19:48:00 +0000 |
1293 | +++ unittests/storagemanager/tst_storagemanager.cpp 2016-02-23 11:36:01 +0000 |
1294 | @@ -22,6 +22,8 @@ |
1295 | |
1296 | #define private public |
1297 | #include "storagemanager.h" |
1298 | +#include "data_validjpeg.h" |
1299 | +#include "data_noexifjpeg.h" |
1300 | |
1301 | const QLatin1String testPath("/tmp/aalCameraStorageManagerUnitTestDirectory0192837465/"); |
1302 | |
1303 | @@ -34,6 +36,7 @@ |
1304 | void checkDirectory(); |
1305 | void fileNameGenerator_data(); |
1306 | void fileNameGenerator(); |
1307 | + void updateEXIF(); |
1308 | |
1309 | private: |
1310 | void removeTestDirectory(); |
1311 | @@ -112,6 +115,25 @@ |
1312 | dir.rmdir(testPath); |
1313 | } |
1314 | |
1315 | +void tst_StorageManager::updateEXIF() |
1316 | +{ |
1317 | + StorageManager storage; |
1318 | + bool result; |
1319 | + QTemporaryFile tmp; |
1320 | + QVariantMap metadata; |
1321 | + QByteArray invalidJPEG("INVALID_IMAGE"); |
1322 | + result = storage.updateJpegMetadata(invalidJPEG, metadata, &tmp); |
1323 | + QCOMPARE(result, false); |
1324 | + result = storage.updateJpegMetadata(invalidJPEG, metadata, 0); |
1325 | + QCOMPARE(result, false); |
1326 | + result = storage.updateJpegMetadata(invalidJPEG, metadata, &tmp); |
1327 | + QCOMPARE(result, false); |
1328 | + result = storage.updateJpegMetadata(QByteArray((char*)data_validjpeg, data_validjpeg_len), metadata, &tmp); |
1329 | + QCOMPARE(result, true); |
1330 | + result = storage.updateJpegMetadata(QByteArray((char*)data_noexifjpeg, data_noexifjpeg_len), metadata, &tmp); |
1331 | + QCOMPARE(result, true); |
1332 | +} |
1333 | + |
1334 | QTEST_GUILESS_MAIN(tst_StorageManager); |
1335 | |
1336 | #include "tst_storagemanager.moc" |
1337 | |
1338 | === modified file 'unittests/stubs/storagemanager_stub.cpp' |
1339 | --- unittests/stubs/storagemanager_stub.cpp 2014-09-10 19:48:00 +0000 |
1340 | +++ unittests/stubs/storagemanager_stub.cpp 2016-02-23 11:36:01 +0000 |
1341 | @@ -19,8 +19,9 @@ |
1342 | |
1343 | #include "storagemanager.h" |
1344 | |
1345 | -StorageManager::StorageManager() |
1346 | +StorageManager::StorageManager(QObject* parent) |
1347 | { |
1348 | + Q_UNUSED(parent); |
1349 | } |
1350 | |
1351 | QString StorageManager::nextPhotoFileName(const QString &directory) |
1352 | |
1353 | === modified file 'unittests/unittests.pro' |
1354 | --- unittests/unittests.pro 2014-07-14 16:18:14 +0000 |
1355 | +++ unittests/unittests.pro 2016-02-23 11:36:01 +0000 |
1356 | @@ -7,7 +7,6 @@ |
1357 | aalcameraflashcontrol \ |
1358 | aalcamerafocuscontrol \ |
1359 | aalcamerazoomcontrol \ |
1360 | - aalimagecapturecontrol \ |
1361 | aalmediarecordercontrol \ |
1362 | aalvideodeviceselectorcontrol \ |
1363 | aalviewfindersettingscontrol \ |
PASSED: Continuous integration, rev:179 jenkins. qa.ubuntu. com/job/ qtubuntu- camera- ci/139/ jenkins. qa.ubuntu. com/job/ qtubuntu- camera- vivid-amd64- ci/42 jenkins. qa.ubuntu. com/job/ qtubuntu- camera- vivid-armhf- ci/43 jenkins. qa.ubuntu. com/job/ qtubuntu- camera- vivid-armhf- ci/43/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ qtubuntu- camera- vivid-i386- ci/42
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/qtubuntu- camera- ci/139/ rebuild
http://