./0000755000015600001650000000000012675020550011077 5ustar jenkinsjenkins./src/0000755000015600001650000000000012675020554011672 5ustar jenkinsjenkins./src/storagemanager.cpp0000644000015600001650000002216512675020550015377 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "storagemanager.h" #include #include #include #include #include #include #include #include #include #include const QLatin1String photoBase = QLatin1String("image"); const QLatin1String videoBase = QLatin1String("video"); const QLatin1String photoExtension = QLatin1String("jpg"); const QLatin1String videoExtension = QLatin1String("mp4"); const QLatin1String dateFormat = QLatin1String("yyyyMMdd_HHmmsszzz"); StorageManager::StorageManager(QObject* parent) : QObject(parent) { } QString StorageManager::nextPhotoFileName(const QString &directoy) { m_directory = directoy; if (m_directory.isEmpty()) { m_directory = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/" + QCoreApplication::applicationName(); QDir dir; dir.mkpath(m_directory); } return fileNameGenerator(photoBase, photoExtension); } QString StorageManager::nextVideoFileName(const QString &directoy) { m_directory = directoy; if (m_directory.isEmpty()) { m_directory = QStandardPaths::writableLocation(QStandardPaths::MoviesLocation) + "/" + QCoreApplication::applicationName(); QDir dir; dir.mkpath(m_directory); } return fileNameGenerator(videoBase, videoExtension); } bool StorageManager::checkDirectory(const QString &path) const { QFileInfo fi(path); QDir dir; if (fi.isDir()) dir.setPath(path); else dir.setPath(fi.absoluteDir().absolutePath()); if (!dir.exists()) { bool ok = dir.mkpath(dir.absolutePath()); if (!ok) return false; } fi.setFile(dir.absolutePath()); if (!fi.isWritable()) return false; return true; } QString StorageManager::fileNameGenerator(const QString &base, const QString& extension) { QString date = QDateTime::currentDateTime().toString(dateFormat); return QString("%1/%2%3.%4") .arg(m_directory) .arg(base) .arg(date) .arg(extension); } bool StorageManager::updateJpegMetadata(QByteArray data, QVariantMap metadata, QTemporaryFile* destination) { if (data.isEmpty() || destination == 0) return false; Exiv2::Image::AutoPtr image; try { image = Exiv2::ImageFactory::open(static_cast((const unsigned char*)data.constData()), data.size()); if (!image.get()) { return false; } } catch(const Exiv2::AnyError&) { return false; } try { image->readMetadata(); Exiv2::ExifData ed = image->exifData(); const QString now = QDateTime::currentDateTime().toString("yyyy:MM:dd HH:mm:ss"); ed["Exif.Photo.DateTimeOriginal"].setValue(now.toStdString()); ed["Exif.Photo.DateTimeDigitized"].setValue(now.toStdString()); if (metadata.contains("GPSLatitude") && metadata.contains("GPSLongitude") && metadata.contains("GPSTimeStamp")) { // Write all GPS metadata according to version 2.2 of the EXIF spec, // which is what Android did. See: http://www.exiv2.org/Exif2-2.PDF const char version[4] = {2, 2, 0, 0}; Exiv2::DataValue versionValue(Exiv2::unsignedByte); versionValue.read((const Exiv2::byte*)version, 4); ed.add(Exiv2::ExifKey("Exif.GPSInfo.GPSVersionID"), &versionValue); // According to the spec, the GPS processing method is a buffer of type Undefined, which // does not need to be zero terminated. It should be prepended by an 8 byte, zero padded // string specifying the encoding. const char methodHeader[8] = {'A', 'S', 'C', 'I', 'I', 0, 0, 0}; QByteArray method = metadata.value("GPSProcessingMethod").toString().toLatin1(); method.prepend(methodHeader, 8); Exiv2::DataValue methodValue(Exiv2::undefined); methodValue.read((const Exiv2::byte*)method.constData(), method.size()); ed.add(Exiv2::ExifKey("Exif.GPSInfo.GPSProcessingMethod"), &methodValue); double latitude = metadata.value("GPSLatitude").toDouble(); ed["Exif.GPSInfo.GPSLatitude"] = decimalToExifRational(latitude).toStdString(); ed["Exif.GPSInfo.GPSLatitudeRef"] = (latitude < 0 ) ? "S" : "N"; double longitude = metadata.value("GPSLongitude").toDouble(); ed["Exif.GPSInfo.GPSLongitude"] = decimalToExifRational(longitude).toStdString(); ed["Exif.GPSInfo.GPSLongitudeRef"] = (longitude < 0 ) ? "W" : "E"; if (metadata.contains("GPSAltitude")) { // Assume altitude precision to the meter unsigned int altitude = floor(metadata.value("GPSAltitude").toDouble()); Exiv2::URationalValue::AutoPtr altitudeValue(new Exiv2::URationalValue); altitudeValue->value_.push_back(std::make_pair(altitude,1)); ed.add(Exiv2::ExifKey("Exif.GPSInfo.GPSAltitude"), altitudeValue.get()); // Byte field of lenght 1. Value of 0 means the reference is sea level. const char reference = 0; Exiv2::DataValue referenceValue(Exiv2::unsignedByte); referenceValue.read((const Exiv2::byte*) &reference, 1); ed.add(Exiv2::ExifKey("Exif.GPSInfo.GPSAltitudeRef"), &referenceValue); } QDateTime stamp = metadata.value("GPSTimeStamp").toDateTime(); ed["Exif.GPSInfo.GPSTimeStamp"] = stamp.toString("HH/1 mm/1 ss/1").toStdString(); ed["Exif.GPSInfo.GPSDateStamp"] = stamp.toString("yyyy:MM:dd").toStdString(); } image->setExifData(ed); image->writeMetadata(); } catch(const Exiv2::AnyError&) { return false; } if (!destination->open()) { return false; } try { Exiv2::BasicIo& io = image->io(); char* modifiedMetadata = reinterpret_cast(io.mmap()); const long size = io.size(); const qint64 writtenSize = destination->write(modifiedMetadata, size); io.munmap(); destination->close(); return (writtenSize == size); } catch(const Exiv2::AnyError&) { destination->close(); return false; } } SaveToDiskResult StorageManager::saveJpegImage(QByteArray data, QVariantMap metadata, QString fileName, QSize previewResolution, int captureID) { SaveToDiskResult result; QString captureFile; QFileInfo fi(fileName); if (fileName.isEmpty() || fi.isDir()) { captureFile = nextPhotoFileName(fileName); } else { captureFile = fileName; } result.fileName = captureFile; bool diskOk = checkDirectory(captureFile); if (!diskOk) { result.errorMessage = QString("Won't be able to save file %1 to disk").arg(captureFile); return result; } QBuffer buffer(&data); QImageReader reader(&buffer, "jpg"); QSize scaledSize = reader.size(); // fast, as it does not decode the JPEG scaledSize.scale(previewResolution, Qt::KeepAspectRatio); reader.setScaledSize(scaledSize); reader.setQuality(25); QImage image = reader.read(); Q_EMIT previewReady(captureID, image); QTemporaryFile file; if (!updateJpegMetadata(data, metadata, &file)) { qWarning() << "Failed to update EXIF timestamps. Picture will be saved as UTC timezone."; if (!file.open()) { result.errorMessage = QString("Could not open temprary file %1").arg(file.fileName()); return result; } const qint64 writtenSize = file.write(data); file.close(); if (writtenSize != data.size()) { result.errorMessage = QString("Could not write file %1").arg(fileName); return result; } } QFile finalFile(file.fileName()); bool ok = finalFile.rename(captureFile); if (!ok) { result.errorMessage = QString("Could not save image to %1").arg(fileName); return result; } result.success = true; return result; } QString StorageManager::decimalToExifRational(double decimal) { decimal = fabs(decimal); unsigned int degrees = floor(decimal); unsigned int minutes = floor((decimal - degrees) * 60); double seconds = (decimal - degrees - minutes / 60) * 3600; seconds = floor(seconds * 100); return QString("%1/1 %2/1 %3/100").arg(degrees).arg(minutes).arg(seconds); } SaveToDiskResult::SaveToDiskResult() : success(false) { } ./src/audiocapture.h0000644000015600001650000000337612675020550014535 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authored by: Jim Hodapp */ #ifndef AUDIOCAPTURE_H #define AUDIOCAPTURE_H #include #include #include class AalMediaRecorderControl; struct MediaRecorderWrapper; struct pa_simple; class AudioCapture : public QObject { Q_OBJECT typedef void (*RecorderReadAudioCallback)(void *context); public: static const int AUDIO_CAPTURE_GENERAL_ERROR = -1; static const int AUDIO_CAPTURE_TIMEOUT_ERROR = -2; explicit AudioCapture(MediaRecorderWrapper *mediaRecorder); ~AudioCapture(); bool init(RecorderReadAudioCallback callback, void *context); /* Terminates the Pulseaudio reader/writer QThread */ int setupMicrophoneStream(); void stopCapture(); public Q_SLOTS: void run(); private: int readMicrophone(); bool setupPipe(); ssize_t loopWrite(int fd, const void *data, size_t len); int writeDataToPipe(); pa_simple *m_paStream; int16_t m_audioBuf[MIC_READ_BUF_SIZE]; int m_audioPipe; bool m_flagExit; MediaRecorderWrapper *m_mediaRecorder; }; #endif // AUDIOCAPTURE_H ./src/aalcameraexposurecontrol.h0000644000015600001650000000364212675020550017146 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALCAMERAEXPOSURECONTROL_H #define AALCAMERAEXPOSURECONTROL_H #include #include #include class AalCameraService; class CameraControl; class CameraControlListener; class AalCameraExposureControl : public QCameraExposureControl { Q_OBJECT public: explicit AalCameraExposureControl(AalCameraService *service, QObject *parent = 0); void init(CameraControl *control, CameraControlListener *listener); bool setValue(ExposureParameter parameter, const QVariant& value); QVariant requestedValue(ExposureParameter parameter) const; QVariant actualValue(ExposureParameter parameter) const; bool isParameterSupported(ExposureParameter parameter) const; QVariantList supportedParameterRange(ExposureParameter parameter, bool *continuous) const; static void supportedSceneModesCallback(void *context, SceneMode sceneMode); private: QMap m_androidToQtExposureModes; AalCameraService *m_service; QList m_supportedExposureModes; QCameraExposure::ExposureMode m_requestedExposureMode; QCameraExposure::ExposureMode m_actualExposureMode; }; #endif // AALCAMERAEXPOSURECONTROL_H ./src/aalmetadatawritercontrol.h0000644000015600001650000000340112675020550017131 0ustar jenkinsjenkins/* * Copyright (C) 2013-2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALMETADATAWRITERCONTROL_H #define AALMETADATAWRITERCONTROL_H #include #include #include class AalCameraService; /*! * \brief The AalMetaDataWriterControl class handles the writable metadata * Implementation for QMetaDataWriterControl * http://qt-project.org/doc/qt-5.0/qtmultimedia/qmetadatawritercontrol.html * A list of already defined tags is listed here * http://qt-project.org/doc/qt-5.0/qtmultimedia/qmediametadata.html */ class AalMetaDataWriterControl : public QMetaDataWriterControl { Q_OBJECT public: explicit AalMetaDataWriterControl(AalCameraService *service, QObject *parent = 0); QStringList availableMetaData() const; bool isMetaDataAvailable() const; bool isWritable() const; QVariant metaData(const QString & key) const; void setMetaData(const QString & key, const QVariant & value); int orientation() const; int correctedOrientation() const; void clearAllMetaData(); private: AalCameraService *m_service; QMap m_metaData; int m_orientation; }; #endif // AALMETADATAWRITERCONTROL_H ./src/aalcameraservice.cpp0000644000015600001650000002517012675020550015666 0ustar jenkinsjenkins/* * Copyright (C) 2013-2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameracontrol.h" #include "aalcameraflashcontrol.h" #include "aalcamerafocuscontrol.h" #include "aalcameraservice.h" #include "aalcamerazoomcontrol.h" #include "aalimagecapturecontrol.h" #include "aalimageencodercontrol.h" #include "aalmediarecordercontrol.h" #include "aalmetadatawritercontrol.h" #include "aalvideodeviceselectorcontrol.h" #include "aalvideoencodersettingscontrol.h" #include "aalvideorenderercontrol.h" #include "aalviewfindersettingscontrol.h" #include "aalcamerainfocontrol.h" #include "storagemanager.h" #include "aalcameraexposurecontrol.h" #include #include #include #include AalCameraService *AalCameraService::m_service = 0; AalCameraService::AalCameraService(QObject *parent): QMediaService(parent), m_androidControl(0), m_androidListener(0), m_restoreStateWhenApplicationActive(false) { m_service = this; m_storageManager = new StorageManager; m_cameraControl = new AalCameraControl(this); m_flashControl = new AalCameraFlashControl(this); m_focusControl = new AalCameraFocusControl(this); m_zoomControl = new AalCameraZoomControl(this); m_imageCaptureControl = new AalImageCaptureControl(this); m_imageEncoderControl = new AalImageEncoderControl(this); m_mediaRecorderControl = new AalMediaRecorderControl(this); m_metadataWriter = new AalMetaDataWriterControl(this); m_deviceSelectControl = new AalVideoDeviceSelectorControl(this); m_videoEncoderControl = new AalVideoEncoderSettingsControl(this); m_videoOutput = new AalVideoRendererControl(this); m_viewfinderControl = new AalViewfinderSettingsControl(this); m_exposureControl = new AalCameraExposureControl(this); m_infoControl = new AalCameraInfoControl(this); QGuiApplication* application = qobject_cast(QGuiApplication::instance()); m_previousApplicationState = application->applicationState(); connect(application, &QGuiApplication::applicationStateChanged, this, &AalCameraService::onApplicationStateChanged); } AalCameraService::~AalCameraService() { disconnectCamera(); m_cameraControl->setState(QCamera::UnloadedState); delete m_cameraControl; delete m_flashControl; delete m_focusControl; delete m_zoomControl; delete m_imageEncoderControl; delete m_imageCaptureControl; delete m_mediaRecorderControl; delete m_metadataWriter; delete m_deviceSelectControl; delete m_videoEncoderControl; delete m_videoOutput; delete m_viewfinderControl; delete m_exposureControl; delete m_infoControl; if (m_androidControl) android_camera_delete(m_androidControl); delete m_storageManager; } QMediaControl *AalCameraService::requestControl(const char *name) { if (qstrcmp(name, QCameraControl_iid) == 0) return m_cameraControl; if (qstrcmp(name, QCameraFlashControl_iid) == 0) return m_flashControl; if (qstrcmp(name, QCameraFocusControl_iid) == 0) return m_focusControl; if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) return m_imageCaptureControl; if (qstrcmp(name, QImageEncoderControl_iid) == 0) return m_imageEncoderControl; if (qstrcmp(name, QMediaRecorderControl_iid) == 0) return m_mediaRecorderControl; if (qstrcmp(name, QMetaDataWriterControl_iid) == 0) return m_metadataWriter; if (qstrcmp(name, QCameraZoomControl_iid) == 0) return m_zoomControl; if (qstrcmp(name, QVideoDeviceSelectorControl_iid) == 0) return m_deviceSelectControl; if (qstrcmp(name, QVideoEncoderSettingsControl_iid) == 0) return m_videoEncoderControl; if (qstrcmp(name, QVideoRendererControl_iid) == 0) return m_videoOutput; if (qstrcmp(name, QCameraViewfinderSettingsControl_iid) == 0) return m_viewfinderControl; if (qstrcmp(name, QCameraExposureControl_iid) == 0) return m_exposureControl; if (qstrcmp(name, QCameraInfoControl_iid) == 0) return m_infoControl; return 0; } void AalCameraService::releaseControl(QMediaControl *control) { Q_UNUSED(control); } CameraControl *AalCameraService::androidControl() { return m_androidControl; } StorageManager *AalCameraService::storageManager() { return m_storageManager; } bool AalCameraService::connectCamera() { if (m_androidControl) return true; m_androidListener = new CameraControlListener; memset(m_androidListener, 0, sizeof(*m_androidListener)); // if there is only one camera fallback directly to the ID of whatever device we have if (m_deviceSelectControl->deviceCount() == 1) { m_androidControl = android_camera_connect_by_id(m_deviceSelectControl->selectedDevice(), m_androidListener); } else { CameraType device = BACK_FACING_CAMERA_TYPE; if (!isBackCameraUsed()) { device = FRONT_FACING_CAMERA_TYPE; } m_androidControl = android_camera_connect_to(device, m_androidListener); } if (!m_androidControl) { delete m_androidListener; m_androidListener = 0; return false; } m_androidListener->context = m_androidControl; initControls(m_androidControl, m_androidListener); return true; } void AalCameraService::disconnectCamera() { if (m_imageCaptureControl->isCaptureRunning()) { m_imageCaptureControl->cancelCapture(); } stopPreview(); if (m_androidControl) { android_camera_disconnect(m_androidControl); m_androidControl = 0; } if (m_androidListener) { delete m_androidListener; m_androidListener = 0; } } void AalCameraService::startPreview() { if (m_videoOutput) { m_videoOutput->startPreview(); } } void AalCameraService::stopPreview() { if (m_videoOutput) { m_videoOutput->stopPreview(); } } bool AalCameraService::isPreviewStarted() const { if (m_videoOutput) { return m_videoOutput->isPreviewStarted(); } else { return false; } } bool AalCameraService::isCameraActive() const { return m_cameraControl->state() == QCamera::ActiveState; } bool AalCameraService::isBackCameraUsed() const { int deviceIndex = m_deviceSelectControl->selectedDevice(); QString deviceName = m_deviceSelectControl->deviceName(deviceIndex); return m_infoControl->cameraPosition(deviceName) == QCamera::BackFace; } /*! * \brief AalCameraService::enablePhotoMode sets all controls into photo mode */ void AalCameraService::enablePhotoMode() { m_flashControl->init(m_service->androidControl()); m_imageEncoderControl->enablePhotoMode(); m_focusControl->enablePhotoMode(); m_viewfinderControl->setAspectRatio(m_imageEncoderControl->getAspectRatio()); } /*! * \brief AalCameraService::enableVideoMode sets all controls into video mode */ void AalCameraService::enableVideoMode() { m_flashControl->init(m_service->androidControl()); m_focusControl->enableVideoMode(); m_viewfinderControl->setAspectRatio(m_videoEncoderControl->getAspectRatio()); } /*! * \brief AalCameraService::isRecording returns true is a video recording is * currently ongoing * \return */ bool AalCameraService::isRecording() const { return m_mediaRecorderControl->state() != QMediaRecorder::StoppedState; } void AalCameraService::updateCaptureReady() { bool ready = true; if (!(m_cameraControl->state() == QCamera::ActiveState)) ready = false; if (m_imageCaptureControl->isCaptureRunning()) ready = false; if (m_focusControl->isFocusBusy()) ready = false; if (!isPreviewStarted()) ready = false; m_imageCaptureControl->setReady(ready); } void AalCameraService::onApplicationStateChanged() { QGuiApplication* application = qobject_cast(QGuiApplication::instance()); Qt::ApplicationState applicationState = application->applicationState(); if (applicationState == Qt::ApplicationActive) { if (m_restoreStateWhenApplicationActive) { m_cameraControl->setState(m_cameraStateWhenApplicationActive); } } else if (m_previousApplicationState == Qt::ApplicationActive) { m_cameraStateWhenApplicationActive = m_cameraControl->state(); m_restoreStateWhenApplicationActive = true; m_mediaRecorderControl->setState(QMediaRecorder::StoppedState); m_cameraControl->setState(QCamera::UnloadedState); } m_previousApplicationState = applicationState; } /*! * \brief AalCameraService::initControls initialize all the controls for a newly * connected camera * \param camControl * \param listener */ void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener) { m_cameraControl->init(camControl, listener); m_videoOutput->init(camControl, listener); m_viewfinderControl->init(camControl, listener); m_imageEncoderControl->init(camControl); m_imageCaptureControl->init(camControl, listener); m_flashControl->init(camControl); m_focusControl->init(camControl, listener); m_zoomControl->init(camControl, listener); m_videoEncoderControl->init(camControl, listener); m_exposureControl->init(camControl, listener); } QSize AalCameraService::selectSizeWithAspectRatio(const QList &sizes, float targetAspectRatio) const { QSize selectedSize; long selectedPixelCount = 0; const float EPSILON = 0.02; if (!sizes.empty()) { // Loop over all sizes until we find the highest one that matches targetAspectRatio. QList::const_iterator it = sizes.begin(); while (it != sizes.end()) { QSize size = *it; const float aspectRatio = (float)size.width() / (float)size.height(); const long pixelCount = (long)size.width() * (long)size.height(); if (fabs(aspectRatio - targetAspectRatio) < EPSILON && pixelCount > selectedPixelCount) { selectedSize = size; selectedPixelCount = pixelCount; } ++it; } } return selectedSize; } ./src/aalcameraexposurecontrol.cpp0000644000015600001650000001250212675020550017474 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameraexposurecontrol.h" #include "aalcameracontrol.h" #include "aalcameraservice.h" #include #include // Definition of this enum value is duplicated in camera-app static const QCameraExposure::ExposureMode ExposureHdr = static_cast(QCameraExposure::ExposureModeVendor + 1); AalCameraExposureControl::AalCameraExposureControl(AalCameraService *service, QObject *parent) : QCameraExposureControl(parent), m_service(service), m_requestedExposureMode(QCameraExposure::ExposureAuto), m_actualExposureMode(QCameraExposure::ExposureAuto) { m_androidToQtExposureModes[SCENE_MODE_AUTO] = QCameraExposure::ExposureAuto; m_androidToQtExposureModes[SCENE_MODE_ACTION] = QCameraExposure::ExposureSports; m_androidToQtExposureModes[SCENE_MODE_NIGHT] = QCameraExposure::ExposureNight; m_androidToQtExposureModes[SCENE_MODE_PARTY] = QCameraExposure::ExposureAuto; // FIXME: no correspondance m_androidToQtExposureModes[SCENE_MODE_SUNSET] = QCameraExposure::ExposureAuto; // FIXME: no correspondance m_androidToQtExposureModes[SCENE_MODE_HDR] = ExposureHdr; } void AalCameraExposureControl::init(CameraControl *control, CameraControlListener *listener) { Q_UNUSED(listener); m_supportedExposureModes.clear(); android_camera_enumerate_supported_scene_modes(control, &AalCameraExposureControl::supportedSceneModesCallback, this); setValue(QCameraExposureControl::ExposureMode, m_requestedExposureMode); Q_EMIT parameterRangeChanged(QCameraExposureControl::ExposureMode); } void AalCameraExposureControl::supportedSceneModesCallback(void *context, SceneMode sceneMode) { AalCameraExposureControl *self = (AalCameraExposureControl*)context; self->m_supportedExposureModes << self->m_androidToQtExposureModes[sceneMode]; } bool AalCameraExposureControl::setValue(ExposureParameter parameter, const QVariant& value) { if (!value.isValid()) { return false; } if (parameter == QCameraExposureControl::ExposureMode) { if (value.value() != m_requestedExposureMode) { m_requestedExposureMode = value.value(); Q_EMIT requestedValueChanged(QCameraExposureControl::ExposureMode); } if (m_service->androidControl() != NULL && m_supportedExposureModes.contains(m_requestedExposureMode)) { SceneMode sceneMode = m_androidToQtExposureModes.key(m_requestedExposureMode); android_camera_set_scene_mode(m_service->androidControl(), sceneMode); m_actualExposureMode = m_requestedExposureMode; Q_EMIT actualValueChanged(QCameraExposureControl::ExposureMode); return true; } } return false; } QVariant AalCameraExposureControl::requestedValue(ExposureParameter parameter) const { if (parameter == QCameraExposureControl::ExposureMode) { return QVariant::fromValue(m_requestedExposureMode); } return QVariant(); } QVariant AalCameraExposureControl::actualValue(ExposureParameter parameter) const { if (parameter == QCameraExposureControl::ExposureMode) { return QVariant::fromValue(m_actualExposureMode); } return QVariant(); } bool AalCameraExposureControl::isParameterSupported(ExposureParameter parameter) const { switch (parameter) { case QCameraExposureControl::ISO: return false; case QCameraExposureControl::Aperture: return false; case QCameraExposureControl::ShutterSpeed: return false; case QCameraExposureControl::ExposureCompensation: return false; case QCameraExposureControl::FlashPower: return false; case QCameraExposureControl::FlashCompensation: return false; case QCameraExposureControl::TorchPower: return false; case QCameraExposureControl::SpotMeteringPoint: return false; case QCameraExposureControl::ExposureMode: return true; case QCameraExposureControl::MeteringMode: return false; default: return false; } } QVariantList AalCameraExposureControl::supportedParameterRange(ExposureParameter parameter, bool *continuous) const { if (continuous != NULL) { *continuous = false; } if (parameter == QCameraExposureControl::ExposureMode) { QVariantList supported; Q_FOREACH(QCameraExposure::ExposureMode mode, m_supportedExposureModes) { supported << QVariant::fromValue(mode); } return supported; } return QVariantList(); } ./src/aalmediarecordercontrol.cpp0000644000015600001650000004200612675020550017260 0ustar jenkinsjenkins/* * Copyright (C) 2013-2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalmediarecordercontrol.h" #include "aalcameraservice.h" #include "aalmetadatawritercontrol.h" #include "aalvideoencodersettingscontrol.h" #include "aalviewfindersettingscontrol.h" #include "audiocapture.h" #include "storagemanager.h" #include #include #include #include #include #include #include #include #include #include #include const int AalMediaRecorderControl::RECORDER_GENERAL_ERROR; const int AalMediaRecorderControl::RECORDER_NOT_AVAILABLE_ERROR; const int AalMediaRecorderControl::RECORDER_INITIALIZATION_ERROR; const int AalMediaRecorderControl::DURATION_UPDATE_INTERVAL; const QLatin1String AalMediaRecorderControl::PARAM_AUDIO_BITRATE = QLatin1String("audio-param-encoding-bitrate"); const QLatin1String AalMediaRecorderControl::PARAM_AUDIO_CHANNELS = QLatin1String("audio-param-number-of-channels"); const QLatin1String AalMediaRecorderControl::PARAM_AUTIO_SAMPLING = QLatin1String("audio-param-sampling-rate"); const QLatin1String AalMediaRecorderControl::PARAM_LATITUDE = QLatin1String("param-geotag-latitude"); const QLatin1String AalMediaRecorderControl::PARAM_LONGITUDE = QLatin1String("param-geotag-longitude"); const QLatin1String AalMediaRecorderControl::PARAM_ORIENTATION = QLatin1String("video-param-rotation-angle-degrees"); const QLatin1String AalMediaRecorderControl::PARAM_VIDEO_BITRATE = QLatin1String("video-param-encoding-bitrate"); /*! * \brief AalMediaRecorderControl::AalMediaRecorderControl * \param service * \param parent */ AalMediaRecorderControl::AalMediaRecorderControl(AalCameraService *service, QObject *parent) : QMediaRecorderControl(parent), m_service(service), m_mediaRecorder(0), m_audioCapture(0), m_outfd(-1), m_duration(0), m_currentState(QMediaRecorder::StoppedState), m_currentStatus(QMediaRecorder::UnloadedStatus), m_recordingTimer(0), m_audioCaptureAvailable(false) { } /*! * \brief AalMediaRecorderControl::~AalMediaRecorderControl */ AalMediaRecorderControl::~AalMediaRecorderControl() { delete m_recordingTimer; if (m_outfd != -1) { int err = close(m_outfd); if (err < 0) qWarning() << "Failed to close recording output file descriptor (errno: " << errno << ")"; } deleteRecorder(); m_audioCaptureThread.quit(); m_audioCaptureThread.wait(); } /*! * \reimp */ void AalMediaRecorderControl::applySettings() { qDebug() << Q_FUNC_INFO << " is not used"; } /*! * \reimp */ qint64 AalMediaRecorderControl::duration() const { return m_duration; } /*! * \reimp */ bool AalMediaRecorderControl::isMuted() const { qDebug() << Q_FUNC_INFO << " is not used"; return false; } /*! * \reimp */ QUrl AalMediaRecorderControl::outputLocation() const { return m_outputLocation; } /*! * \reimp */ bool AalMediaRecorderControl::setOutputLocation(const QUrl &location) { if ( m_outputLocation == location) return true; m_outputLocation = location; return true; } /*! * \reimp */ QMediaRecorder::State AalMediaRecorderControl::state() const { return m_currentState; } /*! * \reimp */ QMediaRecorder::Status AalMediaRecorderControl::status() const { return m_currentStatus; } /*! * \reimp */ qreal AalMediaRecorderControl::volume() const { qDebug() << Q_FUNC_INFO << " is not used"; return 1.0; } /*! * \brief Starts the main microphone reader/writer loop in AudioCapture (run) */ void AalMediaRecorderControl::startAudioCaptureThread() { qDebug() << "Starting microphone reader/writer thread"; // Start the microphone read/write thread m_audioCaptureThread.start(); Q_EMIT audioCaptureThreadStarted(); } /*! * \brief AalMediaRecorderControl::init makes sure the mediarecorder is * initialized */ bool AalMediaRecorderControl::initRecorder() { if (m_mediaRecorder == 0) { m_mediaRecorder = android_media_new_recorder(); if (m_mediaRecorder == 0) { qWarning() << "Unable to create new media recorder"; Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "Unable to create new media recorder"); return false; } int audioInitError = initAudioCapture(); if (audioInitError == 0) { m_audioCaptureAvailable = true; } else { m_audioCaptureAvailable = false; if (audioInitError == AudioCapture::AUDIO_CAPTURE_TIMEOUT_ERROR) { deleteRecorder(); return false; } } android_recorder_set_error_cb(m_mediaRecorder, &AalMediaRecorderControl::errorCB, this); android_camera_unlock(m_service->androidControl()); } return true; } /*! * \brief AalMediaRecorderControl::deleteRecorder releases all resources and * deletes the MediaRecorder */ void AalMediaRecorderControl::deleteRecorder() { deleteAudioCapture(); if (m_mediaRecorder == 0) return; android_recorder_release(m_mediaRecorder); m_mediaRecorder = 0; android_camera_lock(m_service->androidControl()); setStatus(QMediaRecorder::UnloadedStatus); } int AalMediaRecorderControl::initAudioCapture() { // setting up audio recording; m_audioCapture is executed within the m_workerThread affinity m_audioCapture = new AudioCapture(m_mediaRecorder); int audioInitError = m_audioCapture->setupMicrophoneStream(); if (audioInitError != 0) { qWarning() << "Failed to setup PulseAudio microphone recording stream"; delete m_audioCapture; m_audioCapture = 0; } else { m_audioCapture->moveToThread(&m_audioCaptureThread); // startWorkerThread signal comes from an Android layer callback that resides down in // the AudioRecordHybris class connect(this, SIGNAL(audioCaptureThreadStarted()), m_audioCapture, SLOT(run())); // Call recorderReadAudioCallback when the reader side of the named pipe has been setup m_audioCapture->init(&AalMediaRecorderControl::recorderReadAudioCallback, this); } return audioInitError; } void AalMediaRecorderControl::deleteAudioCapture() { if (m_audioCapture == 0) return; m_audioCapture->stopCapture(); m_audioCaptureThread.quit(); m_audioCaptureThread.wait(); delete m_audioCapture; m_audioCapture = 0; m_audioCaptureAvailable = false; } /*! * \brief AalMediaRecorderControl::errorCB handles errors from the android layer * \param context */ void AalMediaRecorderControl::errorCB(void *context) { Q_UNUSED(context); QMetaObject::invokeMethod(AalCameraService::instance()->mediaRecorderControl(), "handleError", Qt::QueuedConnection); } MediaRecorderWrapper* AalMediaRecorderControl::mediaRecorder() const { return m_mediaRecorder; } AudioCapture *AalMediaRecorderControl::audioCapture() const { return m_audioCapture; } /*! * \reimp */ void AalMediaRecorderControl::setMuted(bool muted) { Q_UNUSED(muted); qDebug() << Q_FUNC_INFO << " is not used"; } /*! * \reimp */ void AalMediaRecorderControl::setState(QMediaRecorder::State state) { if (m_currentState == state) return; switch (state) { case QMediaRecorder::RecordingState: { startRecording(); break; } case QMediaRecorder::StoppedState: { stopRecording(); break; } case QMediaRecorder::PausedState: { qDebug() << Q_FUNC_INFO << " pause not used for video recording."; break; } } } /*! * \reimp */ void AalMediaRecorderControl::setVolume(qreal gain) { Q_UNUSED(gain); qDebug() << Q_FUNC_INFO << " is not used"; } void AalMediaRecorderControl::updateDuration() { m_duration += DURATION_UPDATE_INTERVAL; Q_EMIT durationChanged(m_duration); } /*! * \brief AalMediaRecorderControl::handleError emits errors from android layer */ void AalMediaRecorderControl::handleError() { Q_EMIT error(RECORDER_GENERAL_ERROR, "Error on recording video"); } /*! * \brief AalMediaRecorderControl::setStatus * \param status */ void AalMediaRecorderControl::setStatus(QMediaRecorder::Status status) { if (m_currentStatus == status) return; m_currentStatus = status; Q_EMIT statusChanged(m_currentStatus); } /*! * \brief AalMediaRecorderControl::startRecording starts a video record. * FIXME add support for recording audio only */ int AalMediaRecorderControl::startRecording() { if (m_service->androidControl() == 0) { Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "No camera connection"); return RECORDER_INITIALIZATION_ERROR; } if (m_currentStatus != QMediaRecorder::UnloadedStatus) { qWarning() << "Can't start a recording while another one is in progess"; return RECORDER_NOT_AVAILABLE_ERROR; } setStatus(QMediaRecorder::LoadingStatus); m_duration = 0; Q_EMIT durationChanged(m_duration); if (!initRecorder()) { setStatus(QMediaRecorder::UnloadedStatus); return RECORDER_NOT_AVAILABLE_ERROR; } QVideoEncoderSettings videoSettings = m_service->videoEncoderControl()->videoSettings(); int ret; ret = android_recorder_setCamera(m_mediaRecorder, m_service->androidControl()); if (ret < 0) { deleteRecorder(); Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setCamera() failed\n"); return RECORDER_INITIALIZATION_ERROR; } // state initial / idle if (m_audioCaptureAvailable) { ret = android_recorder_setAudioSource(m_mediaRecorder, ANDROID_AUDIO_SOURCE_CAMCORDER); if (ret < 0) { deleteRecorder(); Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setAudioSource() failed"); return RECORDER_INITIALIZATION_ERROR; } } ret = android_recorder_setVideoSource(m_mediaRecorder, ANDROID_VIDEO_SOURCE_CAMERA); if (ret < 0) { deleteRecorder(); Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setVideoSource() failed"); return RECORDER_INITIALIZATION_ERROR; } // state initialized ret = android_recorder_setOutputFormat(m_mediaRecorder, ANDROID_OUTPUT_FORMAT_MPEG_4); if (ret < 0) { deleteRecorder(); Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setOutputFormat() failed"); return RECORDER_INITIALIZATION_ERROR; } // state DataSourceConfigured if (m_audioCaptureAvailable) { ret = android_recorder_setAudioEncoder(m_mediaRecorder, ANDROID_AUDIO_ENCODER_AAC); if (ret < 0) { deleteRecorder(); Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setAudioEncoder() failed"); return RECORDER_INITIALIZATION_ERROR; } } // FIXME set codec from settings ret = android_recorder_setVideoEncoder(m_mediaRecorder, ANDROID_VIDEO_ENCODER_H264); if (ret < 0) { deleteRecorder(); Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setVideoEncoder() failed"); return RECORDER_INITIALIZATION_ERROR; } QString fileName = m_outputLocation.path(); QFileInfo fileInfo = QFileInfo(fileName); if (fileName.isEmpty()) { fileName = m_service->storageManager()->nextVideoFileName(); } else if (fileInfo.isDir()) { fileName = m_service->storageManager()->nextVideoFileName(fileName); } Q_EMIT actualLocationChanged(QUrl(fileName)); m_outfd = open(fileName.toLocal8Bit().data(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (m_outfd < 0) { deleteRecorder(); Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "Could not open file for video recording"); return RECORDER_INITIALIZATION_ERROR; } ret = android_recorder_setOutputFile(m_mediaRecorder, m_outfd); if (ret < 0) { close(m_outfd); m_outfd = -1; deleteRecorder(); Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setOutputFile() failed"); return RECORDER_INITIALIZATION_ERROR; } QSize resolution = videoSettings.resolution(); ret = android_recorder_setVideoSize(m_mediaRecorder, resolution.width(), resolution.height()); if (ret < 0) { close(m_outfd); m_outfd = -1; deleteRecorder(); Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setVideoSize() failed"); return RECORDER_INITIALIZATION_ERROR; } ret = android_recorder_setVideoFrameRate(m_mediaRecorder, videoSettings.frameRate()); if (ret < 0) { close(m_outfd); m_outfd = -1; deleteRecorder(); Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_setVideoFrameRate() failed"); return RECORDER_INITIALIZATION_ERROR; } setParameter(PARAM_VIDEO_BITRATE, videoSettings.bitRate()); // FIXME get data from a new AalAudioEncoderSettingsControl setParameter(PARAM_AUDIO_BITRATE, 48000); setParameter(PARAM_AUDIO_CHANNELS, 2); setParameter(PARAM_AUTIO_SAMPLING, 96000); if (m_service->metadataWriterControl()) { int rotation = m_service->metadataWriterControl()->correctedOrientation(); setParameter(PARAM_ORIENTATION, rotation); m_service->metadataWriterControl()->clearAllMetaData(); } ret = android_recorder_prepare(m_mediaRecorder); if (ret < 0) { close(m_outfd); m_outfd = -1; deleteRecorder(); Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_prepare() failed"); return RECORDER_INITIALIZATION_ERROR; } setStatus(QMediaRecorder::LoadedStatus); setStatus(QMediaRecorder::StartingStatus); // state prepared ret = android_recorder_start(m_mediaRecorder); if (ret < 0) { close(m_outfd); m_outfd = -1; deleteRecorder(); Q_EMIT error(RECORDER_INITIALIZATION_ERROR, "android_recorder_start() failed"); return RECORDER_INITIALIZATION_ERROR; } m_currentState = QMediaRecorder::RecordingState; Q_EMIT stateChanged(m_currentState); setStatus(QMediaRecorder::RecordingStatus); if (m_recordingTimer == 0) { m_recordingTimer = new QTimer(this); m_recordingTimer->setInterval(DURATION_UPDATE_INTERVAL); m_recordingTimer->setSingleShot(false); QObject::connect(m_recordingTimer, SIGNAL(timeout()), this, SLOT(updateDuration())); } m_recordingTimer->start(); return 0; } /*! * \brief AalMediaRecorderControl::stopRecording */ void AalMediaRecorderControl::stopRecording() { qDebug() << __PRETTY_FUNCTION__; if (m_mediaRecorder == 0) { qWarning() << "Can't stop recording properly, m_mediaRecorder is NULL"; return; } if (m_currentStatus != QMediaRecorder::RecordingStatus) { qWarning() << "Can't stop a recording that has not started"; return; } setStatus(QMediaRecorder::FinalizingStatus); m_recordingTimer->stop(); int result = android_recorder_stop(m_mediaRecorder); if (result < 0) { Q_EMIT error(RECORDER_GENERAL_ERROR, "Cannot stop video recording"); return; } // Stop microphone reader/writer loop // NOTE: This must come after the android_recorder_stop call, otherwise the // RecordThread instance will block the MPEG4Writer pthread_join when trying to // cleanly stop recording. if (m_audioCapture != 0) { m_audioCapture->stopCapture(); } android_recorder_reset(m_mediaRecorder); int err = close(m_outfd); if (err < 0) qWarning() << "Failed to close recording output file descriptor (errno: " << errno << ")"; m_outfd = -1; m_currentState = QMediaRecorder::StoppedState; Q_EMIT stateChanged(m_currentState); deleteRecorder(); } /*! * \brief AalMediaRecorderControl::setParameter convenient function to set parameters * \param parameter Name of the parameter * \param value value to set */ void AalMediaRecorderControl::setParameter(const QString ¶meter, int value) { Q_ASSERT(m_mediaRecorder); QString param = parameter + QChar('=') + QString::number(value); android_recorder_setParameters(m_mediaRecorder, param.toLocal8Bit().data()); } void AalMediaRecorderControl::recorderReadAudioCallback(void *context) { AalMediaRecorderControl *thiz = static_cast(context); if (thiz != NULL) { thiz->startAudioCaptureThread(); } } ./src/aalcamerazoomcontrol.h0000644000015600001650000000277112675020550016262 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALCAMERAZOOMCONTROL_H #define AALCAMERAZOOMCONTROL_H #include class AalCameraService; class CameraControl; class CameraControlListener; class AalCameraZoomControl : public QCameraZoomControl { Q_OBJECT public: AalCameraZoomControl(AalCameraService *service, QObject *parent = 0); qreal currentDigitalZoom() const; qreal currentOpticalZoom() const; qreal maximumDigitalZoom() const; qreal maximumOpticalZoom() const; qreal requestedDigitalZoom() const; qreal requestedOpticalZoom() const; void zoomTo(qreal optical, qreal digital); void resetZoom(); public Q_SLOTS: void init(CameraControl *control, CameraControlListener *listener); private: AalCameraService *m_service; int m_currentDigitalZoom; int m_maximumDigitalZoom; int m_pendingZoom; }; #endif // AALCAMERAZOOMCONTROL_H ./src/aalimageencodercontrol.cpp0000644000015600001650000002206612675020550017101 0ustar jenkinsjenkins/* * Copyright (C) 2013-2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalimageencodercontrol.h" #include "aalcameracontrol.h" #include "aalviewfindersettingscontrol.h" #include "aalvideoencodersettingscontrol.h" #include "aalimagecapturecontrol.h" #include "aalcameraservice.h" #include #include #include #include AalImageEncoderControl::AalImageEncoderControl(AalCameraService *service, QObject *parent) : QImageEncoderControl(parent), m_service(service), m_currentSize(), m_currentThumbnailSize() { } AalImageEncoderControl::~AalImageEncoderControl() { } QString AalImageEncoderControl::imageCodecDescription(const QString &codec) const { Q_UNUSED(codec); return QString(); } QImageEncoderSettings AalImageEncoderControl::imageSettings() const { return m_encoderSettings; } void AalImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings) { if (!settings.isNull()) { // JPEG quality m_encoderSettings.setQuality(settings.quality()); if (m_service->androidControl()) { int jpegQuality = qtEncodingQualityToJpegQuality(settings.quality()); android_camera_set_jpeg_quality(m_service->androidControl(), jpegQuality); } // codec if (!settings.codec().isNull()) { m_encoderSettings.setCodec(settings.codec()); } // resolution if (!settings.resolution().isNull()) { setSize(settings.resolution()); } // encoding options if (!settings.encodingOptions().isEmpty()) { m_encoderSettings.setEncodingOptions(settings.encodingOptions()); } } } QStringList AalImageEncoderControl::supportedImageCodecs() const { return QStringList(); } QList AalImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const { Q_UNUSED(continuous); Q_UNUSED(settings); return m_availableSizes; } QList AalImageEncoderControl::supportedThumbnailResolutions(const QImageEncoderSettings &settings, bool *continuous) const { Q_UNUSED(continuous); Q_UNUSED(settings); return m_availableThumbnailSizes; } float AalImageEncoderControl::getAspectRatio() const { return (float)m_currentSize.width() / (float)m_currentSize.height(); } void AalImageEncoderControl::init(CameraControl *control) { Q_ASSERT(control != NULL); if (m_availableSizes.isEmpty()) { android_camera_enumerate_supported_picture_sizes(control, &AalImageEncoderControl::getPictureSizeCb, this); android_camera_enumerate_supported_thumbnail_sizes(control, &AalImageEncoderControl::getThumbnailSizeCb, this); } int jpegQuality; android_camera_get_jpeg_quality(control, &jpegQuality); m_encoderSettings.setQuality(jpegQualityToQtEncodingQuality(jpegQuality)); if (m_availableSizes.empty()) { qWarning() << "(AalImageEncoderControl::init) No supported resolutions detected for currently selected camera device." << endl; return; } if (!m_currentSize.isValid() || !m_availableSizes.contains(m_currentSize)) { QSize greatestSize; foreach (const QSize &size, m_availableSizes) { if (size.width() * size.height() > greatestSize.width() * greatestSize.height()) { greatestSize = size; } } setSize(greatestSize); } else { setSize(m_currentSize); } } bool AalImageEncoderControl::setSize(const QSize &size) { CameraControl *cc = m_service->androidControl(); if (!cc) { m_currentSize = size; m_encoderSettings.setResolution(m_currentSize); return true; } if (!m_availableSizes.contains(size)) { qWarning() << "(AalImageEncoderControl::setSize) Size " << size << "is not supported by the camera"; qWarning() << "(AalImageEncoderControl::setSize) Supported sizes are: " << m_availableSizes; return false; } m_currentSize = size; m_encoderSettings.setResolution(m_currentSize); if (m_service->cameraControl()->captureMode() == QCamera::CaptureStillImage) { m_service->viewfinderControl()->setAspectRatio(getAspectRatio()); } // Select m_currentThumbnailSize so that its aspect ratio is the same // as m_currentSize's aspect ratio float imageAspectRatio = getAspectRatio(); float thumbnailAspectRatio; // Set the optimal thumbnail image resolution that will be saved to the JPEG file if (!m_availableThumbnailSizes.empty()) { // Because EXIF thumbnails must be at most 64KB by specification, make sure that // we request thumbnails that are no bigger than 128x128x4 bytes uncompressed // which will ensure that when JPEG compressed they are under 64KB. // Fixes bug https://bugs.launchpad.net/ubuntu/+source/camera-app/+bug/1519766 if (imageAspectRatio >= 1.0) { m_currentThumbnailSize = QSize(128, (int)(128.0f / imageAspectRatio)); } else { m_currentThumbnailSize = QSize((int)(128.0f * imageAspectRatio), 128); } thumbnailAspectRatio = (float)m_currentThumbnailSize.width() / (float)m_currentThumbnailSize.height(); } // Thumbnails will appear squashed or stretched if not the same aspect ratio as the original image. // This will most likely be an incorrect size list supplied to qtubuntu-camera from the camera driver. if (imageAspectRatio != thumbnailAspectRatio) { qWarning() << "(AalImageEncoderControl::setSize) ** Image and thumbnail aspect ratios are different. Thumbnails will look wrong!"; } android_camera_set_picture_size(cc, m_currentSize.width(), m_currentSize.height()); android_camera_set_thumbnail_size(cc, m_currentThumbnailSize.width(), m_currentThumbnailSize.height()); return true; } void AalImageEncoderControl::resetAllSettings() { m_availableSizes.clear(); m_availableThumbnailSizes.clear(); m_currentSize = QSize(); m_currentThumbnailSize = QSize(); } /*! * \brief AalImageEncoderControl::enablePhotoMode prepares the camera to take photos */ void AalImageEncoderControl::enablePhotoMode() { CameraControl *cc = m_service->androidControl(); if (!cc || !m_currentSize.isValid()) { return; } android_camera_set_picture_size(cc, m_currentSize.width(), m_currentSize.height()); android_camera_set_thumbnail_size(cc, m_currentThumbnailSize.width(), m_currentThumbnailSize.height()); } void AalImageEncoderControl::getPictureSizeCb(void *ctx, int width, int height) { if (ctx != NULL) { AalImageEncoderControl *self = static_cast(ctx); self->getPictureSize(width, height); } else qWarning() << "ctx is NULL, cannot get supported camera resolutions." << endl; } void AalImageEncoderControl::getThumbnailSizeCb(void *ctx, int width, int height) { if (ctx != NULL) { AalImageEncoderControl *self = static_cast(ctx); self->getThumbnailSize(width, height); } else qWarning() << "ctx is NULL, cannot get supported thumbnail resolutions." << endl; } void AalImageEncoderControl::getPictureSize(int width, int height) { m_availableSizes.append(QSize(width, height)); } void AalImageEncoderControl::getThumbnailSize(int width, int height) { m_availableThumbnailSizes.append(QSize(width, height)); } QMultimedia::EncodingQuality AalImageEncoderControl::jpegQualityToQtEncodingQuality(int jpegQuality) { QMultimedia::EncodingQuality quality; if (jpegQuality <= 40) { quality = QMultimedia::VeryLowQuality; } else if (jpegQuality <= 60) { quality = QMultimedia::LowQuality; } else if (jpegQuality <= 80) { quality = QMultimedia::NormalQuality; } else if (jpegQuality <= 90) { quality = QMultimedia::HighQuality; } else { quality = QMultimedia::VeryHighQuality; } return quality; } int AalImageEncoderControl::qtEncodingQualityToJpegQuality(QMultimedia::EncodingQuality quality) { int jpegQuality = 100; switch (quality) { case QMultimedia::VeryLowQuality: jpegQuality = 40; break; case QMultimedia::LowQuality: jpegQuality = 60; break; case QMultimedia::NormalQuality: jpegQuality = 80; break; case QMultimedia::HighQuality: jpegQuality = 90; break; case QMultimedia::VeryHighQuality: jpegQuality = 100; break; } return jpegQuality; } ./src/aalimageencodercontrol.h0000644000015600001650000000435312675020550016545 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALIMAGEENCODERCONTROL_H #define AALIMAGEENCODERCONTROL_H #include #include #include #include class AalCameraService; class CameraControl; class AalImageEncoderControl : public QImageEncoderControl { public: AalImageEncoderControl(AalCameraService *service, QObject *parent = 0); ~AalImageEncoderControl(); QString imageCodecDescription(const QString &codec) const; QImageEncoderSettings imageSettings() const; void setImageSettings(const QImageEncoderSettings &settings); QStringList supportedImageCodecs() const; QList supportedResolutions(const QImageEncoderSettings &settings, bool *continuous = 0) const; QList supportedThumbnailResolutions(const QImageEncoderSettings &settings, bool *continuous = 0) const; float getAspectRatio() const; void init(CameraControl *control); void resetAllSettings(); void enablePhotoMode(); static void getPictureSizeCb(void *ctx, int width, int height); static void getThumbnailSizeCb(void *ctx, int width, int height); private: AalCameraService *m_service; QList m_availableSizes; QList m_availableThumbnailSizes; QSize m_currentSize; QSize m_currentThumbnailSize; QImageEncoderSettings m_encoderSettings; bool setSize(const QSize &size); void getPictureSize(int width, int height); void getThumbnailSize(int width, int height); QMultimedia::EncodingQuality jpegQualityToQtEncodingQuality(int jpegQuality); int qtEncodingQualityToJpegQuality(QMultimedia::EncodingQuality quality); }; #endif ./src/aalcameraserviceplugin.cpp0000644000015600001650000000712712675020550017107 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameraserviceplugin.h" #include "aalcameraservice.h" #include #include #include #include #include AalServicePlugin::AalServicePlugin() { } QMediaService* AalServicePlugin::create(QString const& key) { if (key == QLatin1String(Q_MEDIASERVICE_CAMERA)) return new AalCameraService; else qWarning() << "Key not supported:" << key; return 0; } void AalServicePlugin::release(QMediaService *service) { delete service; } QList AalServicePlugin::devices(const QByteArray &service) const { QList deviceList; if (QString::fromLatin1(service) != QLatin1String(Q_MEDIASERVICE_CAMERA)) { return deviceList; } // Devices are identified in android only by their index, so we do the same int cameras = android_camera_get_number_of_devices(); for (int deviceId = 0; deviceId < cameras; deviceId++) { QString camera("%1"); camera = camera.arg(deviceId); deviceList.append(camera.toLatin1()); } return deviceList; } QString AalServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) { if (QString::fromLatin1(service) != QLatin1String(Q_MEDIASERVICE_CAMERA)) { return QString(); } // Android does not provice a descriptive identifier for devices, so we just // send back the index plus some useful human readable information about position. bool ok; int deviceID = device.toInt(&ok, 10); if (!ok || deviceID >= android_camera_get_number_of_devices()) { qWarning() << "Requested description for invalid device ID:" << device; return QString(); } else { QCamera::Position position = cameraPosition(device); return QString("Camera %1%2").arg(QLatin1String(device)) .arg(position == QCamera::FrontFace ? " Front facing" : (position == QCamera::BackFace ? " Back facing" : "")); } } int AalServicePlugin::cameraOrientation(const QByteArray & device) const { int facing; int orientation; bool ok; int deviceID = device.toInt(&ok, 10); if (!ok) { return 0; } int result = android_camera_get_device_info(deviceID, &facing, &orientation); return (result != 0) ? 0 : orientation; } QCamera::Position AalServicePlugin::cameraPosition(const QByteArray & device) const { int facing; int orientation; bool ok; int deviceID = device.toInt(&ok, 10); if (!ok) { return QCamera::UnspecifiedPosition; } int result = android_camera_get_device_info(deviceID, &facing, &orientation); if (result != 0) { return QCamera::UnspecifiedPosition; } else { return facing == BACK_FACING_CAMERA_TYPE ? QCamera::BackFace : QCamera::FrontFace; } } ./src/aalcamerainfocontrol.cpp0000644000015600001650000000211212675020550016551 0ustar jenkinsjenkins/* * Copyright (C) 2016 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcamerainfocontrol.h" #include AalCameraInfoControl::AalCameraInfoControl(QObject *parent) : QCameraInfoControl(parent) { } QCamera::Position AalCameraInfoControl::cameraPosition(const QString &deviceName) const { return QCameraInfo(deviceName.toLatin1()).position(); } int AalCameraInfoControl::cameraOrientation(const QString &deviceName) const { return QCameraInfo(deviceName.toLatin1()).orientation(); } ./src/aalvideorenderercontrol.cpp0000644000015600001650000001531212675020550017310 0ustar jenkinsjenkins/* * Copyright (C) 2012 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalvideorenderercontrol.h" #include "aalcameraservice.h" #include "aalviewfindersettingscontrol.h" #include #include #include #include #include #include #include #include #include class AalGLTextureBuffer : public QAbstractVideoBuffer { public: AalGLTextureBuffer(GLuint textureId) : QAbstractVideoBuffer(QAbstractVideoBuffer::GLTextureHandle), m_textureId(textureId) { } MapMode mapMode() const { return NotMapped; } uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) { qDebug() << Q_FUNC_INFO; Q_UNUSED(mode); Q_UNUSED(numBytes); Q_UNUSED(bytesPerLine); return (uchar*)0; } void unmap() { qDebug() << Q_FUNC_INFO; } QVariant handle() const { return QVariant::fromValue(m_textureId); } GLuint textureId() { return m_textureId; } private: GLuint m_textureId; }; AalVideoRendererControl::AalVideoRendererControl(AalCameraService *service, QObject *parent) : QVideoRendererControl(parent) , m_surface(0), m_service(service), m_viewFinderRunning(false), m_previewStarted(false), m_textureId(0) { // Get notified when qtvideo-node creates a GL texture connect(SharedSignal::instance(), SIGNAL(textureCreated(unsigned int)), this, SLOT(onTextureCreated(unsigned int))); connect(SharedSignal::instance(), SIGNAL(snapshotTaken(QImage)), this, SLOT(onSnapshotTaken(QImage))); } AalVideoRendererControl::~AalVideoRendererControl() { } QAbstractVideoSurface *AalVideoRendererControl::surface() const { return m_surface; } void AalVideoRendererControl::setSurface(QAbstractVideoSurface *surface) { if (m_surface != surface) { m_surface = surface; Q_EMIT surfaceChanged(surface); } } void AalVideoRendererControl::init(CameraControl *control, CameraControlListener *listener) { Q_UNUSED(control); listener->on_preview_texture_needs_update_cb = &AalVideoRendererControl::updateViewfinderFrameCB; // ensures a new texture will be created by qtvideo-node m_textureId = 0; } void AalVideoRendererControl::startPreview() { if (m_previewStarted) { return; } if (!m_service->androidControl()) { qWarning() << "Can't start preview without a CameraControl"; return; } m_previewStarted = true; if (m_textureId) { CameraControl *cc = m_service->androidControl(); android_camera_set_preview_texture(cc, m_textureId); android_camera_start_preview(cc); } // if no texture ID is set to the frame passed to ShaderVideoNode, // a texture ID will be generated and returned via the 'textureCreated' signal // after calling updateViewfinderFrame() updateViewfinderFrame(); m_service->updateCaptureReady(); } void AalVideoRendererControl::stopPreview() { if (!m_previewStarted) { return; } if (!m_service->androidControl()) { qWarning() << "Can't stop preview without a CameraControl"; return; } if (!m_surface) { qWarning() << "Can't stop preview without a QAbstractVideoSurface"; return; } if (m_surface->isActive()) { m_surface->stop(); } CameraControl *cc = m_service->androidControl(); android_camera_stop_preview(cc); // FIXME: missing android_camera_set_preview_size(QSize()) android_camera_set_preview_texture(cc, 0); m_previewStarted = false; m_service->updateCaptureReady(); } bool AalVideoRendererControl::isPreviewStarted() const { return m_previewStarted; } void AalVideoRendererControl::updateViewfinderFrame() { if (!m_service->viewfinderControl()) { qWarning() << "Can't draw video frame without a viewfinder settings control"; return; } if (!m_service->androidControl()) { qWarning() << "Can't draw video frame without camera"; return; } if (!m_surface) { qWarning() << "Can't draw video frame without surface"; return; } QSize vfSize = m_service->viewfinderControl()->currentSize(); QVideoFrame frame(new AalGLTextureBuffer(m_textureId), vfSize, QVideoFrame::Format_RGB32); if (!frame.isValid()) { qWarning() << "Invalid frame"; return; } CameraControl *cc = m_service->androidControl(); frame.setMetaData("CamControl", QVariant::fromValue((void*)cc)); if (!m_surface->isActive()) { QVideoSurfaceFormat format(frame.size(), frame.pixelFormat(), frame.handleType()); if (!m_surface->start(format)) { qWarning() << "Failed to start viewfinder with format:" << format; } } if (m_surface->isActive()) { m_surface->present(frame); } } void AalVideoRendererControl::onTextureCreated(GLuint textureID) { m_textureId = textureID; CameraControl *cc = m_service->androidControl(); if (cc) { android_camera_set_preview_texture(cc, m_textureId); if (m_textureId && m_previewStarted) { android_camera_start_preview(cc); } } m_service->updateCaptureReady(); } void AalVideoRendererControl::onSnapshotTaken(QImage snapshotImage) { m_preview = snapshotImage; Q_EMIT previewReady(); } void AalVideoRendererControl::updateViewfinderFrameCB(void* context) { Q_UNUSED(context); AalVideoRendererControl *self = AalCameraService::instance()->videoOutputControl(); if (self->m_previewStarted) { QMetaObject::invokeMethod(self, "updateViewfinderFrame", Qt::QueuedConnection); } } const QImage &AalVideoRendererControl::preview() const { return m_preview; } void AalVideoRendererControl::createPreview() { if (!m_textureId || !m_service->androidControl()) return; QSize vfSize = m_service->viewfinderControl()->currentSize(); SharedSignal::instance()->setSnapshotSize(vfSize); SharedSignal::instance()->takeSnapshot(m_service->androidControl()); } ./src/aalcameraservice.h0000644000015600001650000001056612675020550015336 0ustar jenkinsjenkins/* * Copyright (C) 2013-2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALCAMERASERVICE_H #define AALCAMERASERVICE_H #include #include #include class AalCameraControl; class AalCameraFlashControl; class AalCameraFocusControl; class AalCameraZoomControl; class AalImageCaptureControl; class AalImageEncoderControl; class AalMediaRecorderControl; class AalMetaDataWriterControl; class AalVideoDeviceSelectorControl; class AalVideoEncoderSettingsControl; class AalVideoRendererControl; class AalViewfinderSettingsControl; class AalCameraExposureControl; class AalCameraInfoControl; class QCameraControl; struct CameraControl; struct CameraControlListener; class StorageManager; class AalCameraService : public QMediaService { Q_OBJECT public: AalCameraService(QObject *parent = 0); ~AalCameraService(); QMediaControl* requestControl(const char *name); void releaseControl(QMediaControl *control); AalCameraControl *cameraControl() const { return m_cameraControl; } AalCameraFlashControl *flashControl() const { return m_flashControl; } AalCameraFocusControl *focusControl() const { return m_focusControl; } AalCameraZoomControl *zoomControl() const { return m_zoomControl; } AalImageCaptureControl *imageCaptureControl() const { return m_imageCaptureControl; } AalImageEncoderControl *imageEncoderControl() const { return m_imageEncoderControl; } AalMediaRecorderControl *mediaRecorderControl() const { return m_mediaRecorderControl; } AalMetaDataWriterControl *metadataWriterControl() const { return m_metadataWriter; } AalVideoDeviceSelectorControl *deviceSelector() const { return m_deviceSelectControl; } AalVideoEncoderSettingsControl *videoEncoderControl() const { return m_videoEncoderControl; } AalVideoRendererControl *videoOutputControl() const { return m_videoOutput; } AalViewfinderSettingsControl *viewfinderControl() const { return m_viewfinderControl; } AalCameraExposureControl *exposureControl() const { return m_exposureControl; } AalCameraInfoControl *infoControl() const { return m_infoControl; } CameraControl *androidControl(); StorageManager *storageManager(); bool connectCamera(); void disconnectCamera(); void startPreview(); void stopPreview(); bool isPreviewStarted() const; bool isCameraActive() const; bool isBackCameraUsed() const; void enablePhotoMode(); void enableVideoMode(); bool isRecording() const; QSize selectSizeWithAspectRatio(const QList &sizes, float targetAspectRatio) const; static AalCameraService *instance() { return m_service; } public Q_SLOTS: void updateCaptureReady(); protected Q_SLOTS: void onApplicationStateChanged(); private: void initControls(CameraControl *camControl, CameraControlListener *listener); static AalCameraService *m_service; AalCameraControl *m_cameraControl; AalCameraFlashControl *m_flashControl; AalCameraFocusControl *m_focusControl; AalCameraZoomControl *m_zoomControl; AalImageCaptureControl *m_imageCaptureControl; AalImageEncoderControl *m_imageEncoderControl; AalMediaRecorderControl *m_mediaRecorderControl; AalMetaDataWriterControl *m_metadataWriter; AalVideoDeviceSelectorControl *m_deviceSelectControl; AalVideoEncoderSettingsControl *m_videoEncoderControl; AalVideoRendererControl *m_videoOutput; AalViewfinderSettingsControl *m_viewfinderControl; AalCameraExposureControl *m_exposureControl; AalCameraInfoControl *m_infoControl; CameraControl *m_androidControl; CameraControlListener *m_androidListener; StorageManager *m_storageManager; bool m_restoreStateWhenApplicationActive; QCamera::State m_cameraStateWhenApplicationActive; Qt::ApplicationState m_previousApplicationState; }; #endif ./src/aalvideoencodersettingscontrol.cpp0000644000015600001650000001342212675020550020702 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalvideoencodersettingscontrol.h" #include "aalcameraservice.h" #include "aalcameracontrol.h" #include "aalviewfindersettingscontrol.h" #include #include const QSize AalVideoEncoderSettingsControl::DEFAULT_SIZE = QSize(1280,720); const int AalVideoEncoderSettingsControl::DEFAULT_FPS = 30; const QString AalVideoEncoderSettingsControl::DEFAULT_CODEC = QString("H.264"); /*! * \brief AalVideoEncoderSettingsControl::AalVideoEncoderSettingsControl * \param service * \param parent */ AalVideoEncoderSettingsControl::AalVideoEncoderSettingsControl(AalCameraService *service, QObject *parent) : QVideoEncoderSettingsControl(parent), m_service(service) { } /*! * \reimp */ void AalVideoEncoderSettingsControl::setVideoSettings(const QVideoEncoderSettings &settings) { bool continuous; if (supportedVideoCodecs().contains(settings.codec())) m_settings.setCodec(settings.codec()); m_settings.setBitRate(settings.bitRate()); if (supportedFrameRates(settings, &continuous).contains(settings.frameRate())) m_settings.setFrameRate(settings.frameRate()); if (supportedResolutions(settings, &continuous).contains(settings.resolution())) { m_settings.setResolution(settings.resolution()); if (m_service->cameraControl()->captureMode() == QCamera::CaptureVideo) { m_service->viewfinderControl()->setAspectRatio(getAspectRatio()); } } // FIXME support more options } /*! * \reimp */ QList AalVideoEncoderSettingsControl::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const { Q_UNUSED(settings); Q_UNUSED(continuous); // FIXME get data from android QList fps; fps << 15 << 30; return fps; } /*! * \reimp */ QList AalVideoEncoderSettingsControl::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const { Q_UNUSED(settings); Q_UNUSED(continuous); if (m_availableSizes.isEmpty()) querySupportedResolution(); return m_availableSizes; } /*! * \reimp */ QStringList AalVideoEncoderSettingsControl::supportedVideoCodecs() const { // FIXME get data from android QStringList codecs; codecs << DEFAULT_CODEC; return codecs; } /*! * \reimp */ QString AalVideoEncoderSettingsControl::videoCodecDescription(const QString &codec) const { return codec; } /*! * \reimp */ QVideoEncoderSettings AalVideoEncoderSettingsControl::videoSettings() const { return m_settings; } /*! * \brief AalMediaRecorderControl::getAspectRatio returns the curent used aspect ratio * \return */ float AalVideoEncoderSettingsControl::getAspectRatio() const { QSize resolution = m_settings.resolution(); return (float)resolution.width() / (float)resolution.height(); } /*! * \brief AalVideoEncoderSettingsControl::init * \param control * \param listener */ void AalVideoEncoderSettingsControl::init(CameraControl *control, CameraControlListener *listener) { Q_UNUSED(control); Q_UNUSED(listener); resetAllSettings(); if (m_availableSizes.isEmpty()) querySupportedResolution(); if (!m_availableSizes.contains(m_settings.resolution()) && !m_availableSizes.empty()) { m_settings.setResolution(m_availableSizes[0]); if (m_service->cameraControl()->captureMode() == QCamera::CaptureVideo) { m_service->viewfinderControl()->setAspectRatio(getAspectRatio()); } } } /*! * \brief AalVideoEncoderSettingsControl::resetAllSettings */ void AalVideoEncoderSettingsControl::resetAllSettings() { m_availableSizes.clear(); int videoBitRate = 7 * DEFAULT_SIZE.width() * DEFAULT_SIZE.height(); m_settings.setBitRate(videoBitRate); m_settings.setCodec(DEFAULT_CODEC); m_settings.setFrameRate(DEFAULT_FPS); m_settings.setResolution(DEFAULT_SIZE.width(), DEFAULT_SIZE.height()); } /*! * \brief AalVideoEncoderSettingsControl::querySupportedResolution gets the * supported resolutions from android, and saves the to the m_availableSizes member */ void AalVideoEncoderSettingsControl::querySupportedResolution() const { CameraControl *cc = m_service->androidControl(); if (!cc) return; AalVideoEncoderSettingsControl *vSettings = const_cast(this); android_camera_enumerate_supported_video_sizes(cc, &AalVideoEncoderSettingsControl::sizeCB, vSettings); if (m_availableSizes.isEmpty()) { // android devices where video and viewfinder are "linked", no sizes are returned // so use the viewfinder sizes m_availableSizes = m_service->viewfinderControl()->supportedSizes(); } } /*! * \brief AalVideoEncoderSettingsControl::sizeCB calback function to get the supported sizes * \param ctx pointer to the AalVideoEncoderSettingsControl object that requests the sizes * \param width * \param height */ void AalVideoEncoderSettingsControl::sizeCB(void *ctx, int width, int height) { AalVideoEncoderSettingsControl *self = (AalVideoEncoderSettingsControl*)ctx; self->m_availableSizes.append(QSize(width, height)); } ./src/aalviewfindersettingscontrol.cpp0000644000015600001650000001474012675020550020402 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalviewfindersettingscontrol.h" #include "aalcameraservice.h" #include "aalvideorenderercontrol.h" #include #include AalViewfinderSettingsControl::AalViewfinderSettingsControl(AalCameraService *service, QObject *parent) :QCameraViewfinderSettingsControl(parent), m_service(service), m_currentSize(), m_aspectRatio(0.0), m_currentFPS(30), m_minFPS(10), m_maxFPS(30) { } AalViewfinderSettingsControl::~AalViewfinderSettingsControl() { } bool AalViewfinderSettingsControl::isViewfinderParameterSupported(ViewfinderParameter parameter) const { if (parameter == QCameraViewfinderSettingsControl::Resolution || parameter == QCameraViewfinderSettingsControl::MinimumFrameRate || parameter == QCameraViewfinderSettingsControl::MaximumFrameRate ) { return true; } return false; } void AalViewfinderSettingsControl::setViewfinderParameter(ViewfinderParameter parameter, const QVariant &value) { if (!isViewfinderParameterSupported(parameter)) { qWarning() << "Viewfinder dos not support parameter " << parameter; return; } switch (parameter) { case QCameraViewfinderSettingsControl::Resolution: setSize(value.toSize()); break; case QCameraViewfinderSettingsControl::MinimumFrameRate: case QCameraViewfinderSettingsControl::MaximumFrameRate: qWarning() << "Camera framerate boundaries are set by the backend"; break; default: break; } } QVariant AalViewfinderSettingsControl::viewfinderParameter(ViewfinderParameter parameter) const { if (!isViewfinderParameterSupported(parameter)) { qWarning() << "Viewfinder dos not support parameter " << parameter; return QVariant(); } switch (parameter) { case QCameraViewfinderSettingsControl::Resolution: return m_currentSize; case QCameraViewfinderSettingsControl::MinimumFrameRate: return m_minFPS; case QCameraViewfinderSettingsControl::MaximumFrameRate: return m_maxFPS; default: break; } return QVariant(); } void AalViewfinderSettingsControl::setSize(const QSize &size) { if (size == m_currentSize) return; CameraControl *cc = m_service->androidControl(); if (!cc) { m_currentSize = size; // will be used on next call of init return; } if (!m_availableSizes.contains(size)) { qWarning() << "Size " << size << "is not supported by the camera"; qWarning() << "Supported sizes are: " << m_availableSizes; return; } m_currentSize = size; bool wasPreviewStarted = m_service->isPreviewStarted(); if (wasPreviewStarted) { m_service->stopPreview(); } android_camera_set_preview_size(cc, m_currentSize.width(), m_currentSize.height()); if (wasPreviewStarted) { m_service->startPreview(); } } QSize AalViewfinderSettingsControl::currentSize() const { return m_currentSize; } /*! * \brief AalViewfinderSettingsControl::supportedSizes returns the supported viewfinder * sizes * \return */ const QList &AalViewfinderSettingsControl::supportedSizes() const { if (m_availableSizes.isEmpty()) { CameraControl *cc = m_service->androidControl(); if (cc) { AalViewfinderSettingsControl *vfControl = const_cast(this); android_camera_enumerate_supported_preview_sizes(cc, &AalViewfinderSettingsControl::sizeCB, vfControl); } } return m_availableSizes; } /*! * \brief AalViewfinderSettingsControl::setAspectRatio sets the viewfinder's aspect ratio * \param ratio the aspect ratio that should be used */ void AalViewfinderSettingsControl::setAspectRatio(float ratio) { if (ratio == m_aspectRatio) return; m_aspectRatio = ratio; // Choose optimal resolution based on the current camera's aspect ratio QSize size = chooseOptimalSize(m_availableSizes); setSize(size); } void AalViewfinderSettingsControl::init(CameraControl *control, CameraControlListener *listener) { Q_UNUSED(listener); if (m_availableSizes.isEmpty()) { android_camera_enumerate_supported_preview_sizes(control, &AalViewfinderSettingsControl::sizeCB, this); } // Choose optimal resolution based on the current camera's aspect ratio if (m_currentSize.isEmpty()) { m_currentSize = chooseOptimalSize(m_availableSizes); } android_camera_set_preview_size(control, m_currentSize.width(), m_currentSize.height()); android_camera_get_preview_fps_range(control, &m_minFPS, &m_maxFPS); m_minFPS /= 1000; m_maxFPS /= 1000; m_currentFPS = m_maxFPS; android_camera_set_preview_fps(control, m_currentFPS); } /*! Resets all data, so a new init starts with a fresh start This is used when switching the cameras Only works when there is no camera active/connected */ void AalViewfinderSettingsControl::resetAllSettings() { if (m_service->androidControl()) return; m_currentSize = QSize(); m_availableSizes.clear(); m_currentFPS = 0; m_minFPS = 0; m_maxFPS = 0; } void AalViewfinderSettingsControl::sizeCB(void *ctx, int width, int height) { AalViewfinderSettingsControl *self = (AalViewfinderSettingsControl*)ctx; self->m_availableSizes.append(QSize(width, height)); } QSize AalViewfinderSettingsControl::chooseOptimalSize(const QList &sizes) const { if (!sizes.empty()) { if (m_aspectRatio == 0) { // There are resolutions supported, choose one non-optimal one): return sizes[1]; } else { return m_service->selectSizeWithAspectRatio(sizes, m_aspectRatio); } } return QSize(); } ./src/aalmetadatawritercontrol.cpp0000644000015600001650000000612712675020550017474 0ustar jenkinsjenkins/* * Copyright (C) 2013-2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalmetadatawritercontrol.h" #include "aalcameraservice.h" /*! * \brief AalMetaDataWriterControl::AalMetaDataWriterControl * \param service * \param parent */ AalMetaDataWriterControl::AalMetaDataWriterControl(AalCameraService *service, QObject *parent) : QMetaDataWriterControl(parent), m_service(service), m_orientation(0) { Q_ASSERT(service); } /*! * \brief AalMetaDataWriterControl::availableMetaData \reimp * \return */ QStringList AalMetaDataWriterControl::availableMetaData() const { QStringList keys; keys.reserve(m_metaData.size()); QMap::const_iterator i = m_metaData.constBegin(); while (i != m_metaData.constEnd()) { keys.append(i.key()); ++i; } return keys; } /*! * \brief AalMetaDataWriterControl::isMetaDataAvailable \reimp * \return */ bool AalMetaDataWriterControl::isMetaDataAvailable() const { return !m_metaData.isEmpty(); } /*! * \brief AalMetaDataWriterControl::isWritable \reimp * \return */ bool AalMetaDataWriterControl::isWritable() const { return true; } /*! * \brief AalMetaDataWriterControl::metaData \reimp * \param key * \return */ QVariant AalMetaDataWriterControl::metaData(const QString &key) const { if (m_metaData.contains(key)) return m_metaData[key]; return QVariant(); } /*! * \brief AalMetaDataWriterControl::setMetaData \reimp * \param key * \param value */ void AalMetaDataWriterControl::setMetaData(const QString &key, const QVariant &value) { m_metaData[key] = value; if (key == QLatin1String("Orientation")) m_orientation = value.toInt(); } /*! * \brief AalMetaDataWriterControl::orientation returns the orientation of the device, as set by the * app in degrees. * \return orientation, set by the app. Defaults is 0 */ int AalMetaDataWriterControl::orientation() const { return m_orientation; } /*! * \brief AalMetaDataWriterControl::correctedOrientation returns the orientation * depending on which camera is active, the value is adapted * \return */ int AalMetaDataWriterControl::correctedOrientation() const { int rotation = m_orientation % 360; // the front camera rotates the other way round if (!m_service->isBackCameraUsed()) rotation = (360 - rotation) % 360; return rotation; } /*! * \brief AalMetaDataWriterControl::clearMetaData removes all metadata */ void AalMetaDataWriterControl::clearAllMetaData() { m_orientation = 0; m_metaData.clear(); } ./src/storagemanager.h0000644000015600001650000000341212675020550015036 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef STORAGEMANAGER_H #define STORAGEMANAGER_H #include #include #include #include #include class SaveToDiskResult { public: SaveToDiskResult(); bool success; QString fileName; QString errorMessage; }; class StorageManager : public QObject { Q_OBJECT public: explicit StorageManager(QObject* parent = 0); QString nextPhotoFileName(const QString &directoy = QString()); QString nextVideoFileName(const QString &directoy = QString()); bool checkDirectory(const QString &path) const; SaveToDiskResult saveJpegImage(QByteArray data, QVariantMap metadata, QString fileName, QSize previewResolution, int captureID); Q_SIGNALS: void previewReady(int captureID, QImage image); private: QString fileNameGenerator(const QString &base, const QString &extension); bool updateJpegMetadata(QByteArray data, QVariantMap metadata, QTemporaryFile* destination); QString decimalToExifRational(double decimal); QString m_directory; }; #endif // STORAGEMANAGER_H ./src/aalimagecapturecontrol.cpp0000644000015600001650000001511712675020554017130 0ustar jenkinsjenkins/* * Copyright (C) 2013-2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameraservice.h" #include "aalimagecapturecontrol.h" #include "aalimageencodercontrol.h" #include "aalmetadatawritercontrol.h" #include "aalvideorenderercontrol.h" #include "aalviewfindersettingscontrol.h" #include "storagemanager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include AalImageCaptureControl::AalImageCaptureControl(AalCameraService *service, QObject *parent) : QCameraImageCaptureControl(parent), m_service(service), m_cameraControl(service->cameraControl()), m_lastRequestId(0), m_ready(false), m_targetFileName(), m_captureCancelled(false), m_screenAspectRatio(0.0), m_audioPlayer(new QMediaPlayer(this)) { m_galleryPath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation); m_audioPlayer->setMedia(QUrl::fromLocalFile("/system/media/audio/ui/camera_click.ogg")); m_audioPlayer->setAudioRole(QAudio::NotificationRole); QObject::connect(&m_storageManager, &StorageManager::previewReady, this, &AalImageCaptureControl::imageCaptured); } AalImageCaptureControl::~AalImageCaptureControl() { delete(m_audioPlayer); } bool AalImageCaptureControl::isReadyForCapture() const { return m_ready; } int AalImageCaptureControl::capture(const QString &fileName) { m_lastRequestId++; if (!m_ready || !m_service->androidControl()) { emit error(m_lastRequestId, QCameraImageCapture::NotReadyError, QLatin1String("Camera not ready to capture")); return m_lastRequestId; } m_targetFileName = fileName; m_captureCancelled = false; AalMetaDataWriterControl* metadataControl = m_service->metadataWriterControl(); int rotation = metadataControl->correctedOrientation(); android_camera_set_rotation(m_service->androidControl(), rotation); android_camera_take_snapshot(m_service->androidControl()); m_service->updateCaptureReady(); return m_lastRequestId; } void AalImageCaptureControl::cancelCapture() { m_captureCancelled = true; m_targetFileName.clear(); } void AalImageCaptureControl::shutterCB(void *context) { Q_UNUSED(context); QMetaObject::invokeMethod(AalCameraService::instance()->imageCaptureControl(), "shutter", Qt::QueuedConnection); } void AalImageCaptureControl::saveJpegCB(void *data, uint32_t data_size, void *context) { Q_UNUSED(context); // Copy the data buffer so that it is safe to pass it off to another thread, // since it will be destroyed once this function returns QByteArray dataCopy((const char*)data, data_size); QMetaObject::invokeMethod(AalCameraService::instance()->imageCaptureControl(), "saveJpeg", Qt::QueuedConnection, Q_ARG(QByteArray, dataCopy)); } void AalImageCaptureControl::init(CameraControl *control, CameraControlListener *listener) { Q_UNUSED(control); listener->on_msg_shutter_cb = &AalImageCaptureControl::shutterCB; listener->on_data_compressed_image_cb = &AalImageCaptureControl::saveJpegCB; connect(m_service->videoOutputControl(), SIGNAL(previewReady()), this, SLOT(onPreviewReady())); } void AalImageCaptureControl::setReady(bool ready) { if (m_ready != ready) { m_ready = ready; Q_EMIT readyForCaptureChanged(m_ready); } } bool AalImageCaptureControl::isCaptureRunning() const { return !m_targetFileName.isEmpty(); } void AalImageCaptureControl::shutter() { bool playShutterSound = m_settings.value("playShutterSound", true).toBool(); if (playShutterSound) { m_audioPlayer->play(); } Q_EMIT imageExposed(m_lastRequestId); } void AalImageCaptureControl::saveJpeg(const QByteArray& data) { if (m_captureCancelled) { m_captureCancelled = false; return; } // Copy the metadata so that we can clear its container QVariantMap metadata; AalMetaDataWriterControl* metadataControl = m_service->metadataWriterControl(); Q_FOREACH(QString key, metadataControl->availableMetaData()) { metadata.insert(key, metadataControl->metaData(key)); } m_service->metadataWriterControl()->clearAllMetaData(); QString fileName = m_targetFileName; m_targetFileName.clear(); AalViewfinderSettingsControl* viewfinder = m_service->viewfinderControl(); QSize resolution = viewfinder->viewfinderParameter(QCameraViewfinderSettingsControl::Resolution).toSize(); // Restart the viewfinder and notify that the camera is ready to capture again if (m_service->androidControl()) { android_camera_start_preview(m_service->androidControl()); } m_service->updateCaptureReady(); DiskWriteWatcher* watcher = new DiskWriteWatcher(this); QObject::connect(watcher, &QFutureWatcher::finished, this, &AalImageCaptureControl::onImageFileSaved); m_pendingSaveOperations.insert(watcher, m_lastRequestId); QFuture future = QtConcurrent::run(&m_storageManager, &StorageManager::saveJpegImage, data, metadata, fileName, resolution, m_lastRequestId); watcher->setFuture(future); } void AalImageCaptureControl::onImageFileSaved() { DiskWriteWatcher* watcher = static_cast(sender()); if (m_pendingSaveOperations.contains(watcher)) { int requestID = m_pendingSaveOperations.take(watcher); SaveToDiskResult result = watcher->result(); delete watcher; if (result.success) { Q_EMIT imageSaved(requestID, result.fileName); } else { Q_EMIT error(requestID, QCameraImageCapture::ResourceError, result.errorMessage); } } } ./src/aalvideodeviceselectorcontrol.h0000644000015600001650000000250712675020550020151 0ustar jenkinsjenkins/* * Copyright (C) 2012 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALVIDEODEVICESELECTORCONTROL_H #define AALVIDEODEVICESELECTORCONTROL_H #include class AalCameraService; class AalVideoDeviceSelectorControl : public QVideoDeviceSelectorControl { public: AalVideoDeviceSelectorControl(AalCameraService *service, QObject *parent = 0); int defaultDevice() const; int deviceCount() const; QString deviceDescription(int index) const; QString deviceName(int index) const; int selectedDevice() const; public Q_SLOTS: void setSelectedDevice(int index); private: AalCameraService *m_service; int m_currentDevice; mutable int m_numberOfCameras; }; #endif // AALVIDEODEVICESELECTORCONTROL_H ./src/aalcamerafocuscontrol.h0000644000015600001650000000427112675020550016412 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALCAMERAFOCUSCONTROL_H #define AALCAMERAFOCUSCONTROL_H #include #include #include class AalCameraService; class AalCameraFocusControl : public QCameraFocusControl { Q_OBJECT public: AalCameraFocusControl(AalCameraService *service, QObject *parent = 0); QPointF customFocusPoint() const; QCameraFocus::FocusModes focusMode() const; QCameraFocus::FocusPointMode focusPointMode() const; QCameraFocusZoneList focusZones() const; bool isFocusModeSupported(QCameraFocus::FocusModes mode) const; bool isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const; void setCustomFocusPoint(const QPointF & point); void setFocusMode(QCameraFocus::FocusModes mode); void setFocusPointMode(QCameraFocus::FocusPointMode mode); static void focusCB(void* context); bool isFocusBusy() const; void enablePhotoMode(); void enableVideoMode(); public Q_SLOTS: void init(CameraControl *control, CameraControlListener *listener); void startFocus(); private: AutoFocusMode qt2Android(QCameraFocus::FocusModes mode); QCameraFocus::FocusModes android2Qt(AutoFocusMode mode); FocusRegion point2Region(const QPointF &point) const; AalCameraService *m_service; QCameraFocus::FocusModes m_focusMode; QCameraFocus::FocusPointMode m_focusPointMode; QPointF m_focusPoint; FocusRegion m_focusRegion; bool m_focusRunning; }; #endif // AALCAMERAFOCUSCONTROL_H ./src/aalcameraserviceplugin.h0000644000015600001650000000305712675020550016552 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALSERVICEPLUGIN_H #define AALSERVICEPLUGIN_H #include class AalServicePlugin : public QMediaServiceProviderPlugin, public QMediaServiceSupportedDevicesInterface, public QMediaServiceCameraInfoInterface { Q_OBJECT Q_INTERFACES(QMediaServiceSupportedDevicesInterface) Q_INTERFACES(QMediaServiceCameraInfoInterface) Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "aalcamera.json") public: AalServicePlugin(); QMediaService* create(QString const& key); void release(QMediaService *service); QList devices(const QByteArray &service) const; QString deviceDescription(const QByteArray &service, const QByteArray &device); int cameraOrientation(const QByteArray & device) const; QCamera::Position cameraPosition(const QByteArray & device) const; }; #endif ./src/aalcamerafocuscontrol.cpp0000644000015600001650000001472412675020550016751 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcamerafocuscontrol.h" #include "aalcameracontrol.h" #include "aalcameraservice.h" #include #include #include /// The size of the full sensor is +/- of this one in x and y const int focusFullSize = 1000; /// The size of the focus area is +/- of this one in x and y const int focusRegionSize = 100; AalCameraFocusControl::AalCameraFocusControl(AalCameraService *service, QObject *parent) : QCameraFocusControl(parent), m_service(service), m_focusMode(QCameraFocus::AutoFocus), m_focusPointMode(QCameraFocus::FocusPointAuto), m_focusPoint(0.0, 0.0), m_focusRunning(false) { m_focusRegion.left = 0.0; m_focusRegion.right = 0.0; m_focusRegion.top = 0.0; m_focusRegion.bottom = 0.0; m_focusRegion.weight = -9.9; } QPointF AalCameraFocusControl::customFocusPoint() const { return m_focusPoint; } QCameraFocus::FocusModes AalCameraFocusControl::focusMode() const { return m_focusMode; } QCameraFocus::FocusPointMode AalCameraFocusControl::focusPointMode() const { return m_focusPointMode; } QCameraFocusZoneList AalCameraFocusControl::focusZones() const { return QCameraFocusZoneList(); } bool AalCameraFocusControl::isFocusModeSupported(QCameraFocus::FocusModes mode) const { if (mode == QCameraFocus::HyperfocalFocus) return false; return true; } bool AalCameraFocusControl::isFocusPointModeSupported(QCameraFocus::FocusPointMode mode) const { if (mode == QCameraFocus::FocusPointFaceDetection) return false; return true; } void AalCameraFocusControl::setCustomFocusPoint(const QPointF &point) { if (m_focusPoint == point) return; m_focusPoint = point; m_focusRegion = point2Region(m_focusPoint); Q_EMIT customFocusPointChanged(m_focusPoint); if (m_service->androidControl()) { android_camera_set_focus_region(m_service->androidControl(), &m_focusRegion); startFocus(); } } void AalCameraFocusControl::setFocusMode(QCameraFocus::FocusModes mode) { if (m_focusMode == mode || !isFocusModeSupported(mode)) return; m_focusRunning = false; m_service->updateCaptureReady(); AutoFocusMode focusMode = qt2Android(mode); m_focusMode = mode; if (m_service->androidControl()) { android_camera_set_auto_focus_mode(m_service->androidControl(), focusMode); } Q_EMIT focusModeChanged(m_focusMode); } void AalCameraFocusControl::setFocusPointMode(QCameraFocus::FocusPointMode mode) { if (m_focusPointMode == mode || !isFocusPointModeSupported(mode)) return; m_focusPointMode = mode; Q_EMIT focusPointModeChanged(m_focusPointMode); } void AalCameraFocusControl::focusCB(void *context) { Q_UNUSED(context); AalCameraService::instance()->focusControl()->m_focusRunning = false; QMetaObject::invokeMethod(AalCameraService::instance(), "updateCaptureReady", Qt::QueuedConnection); } bool AalCameraFocusControl::isFocusBusy() const { return m_focusRunning; } /*! * \brief AalCameraFocusControl::enablePhotoMode resets the last focus mode for photos */ void AalCameraFocusControl::enablePhotoMode() { setFocusMode(QCameraFocus::AutoFocus); } /*! * \brief AalCameraFocusControl::enableVideoMode sets the focus mode to continuous for video */ void AalCameraFocusControl::enableVideoMode() { setFocusMode(QCameraFocus::ContinuousFocus); } void AalCameraFocusControl::init(CameraControl *control, CameraControlListener *listener) { listener->on_msg_focus_cb = &AalCameraFocusControl::focusCB; AutoFocusMode mode = qt2Android(m_focusMode); android_camera_set_auto_focus_mode(control, mode); m_focusRunning = false; m_service->updateCaptureReady(); } void AalCameraFocusControl::startFocus() { if (!m_service->androidControl()) return; m_focusRunning = true; m_service->updateCaptureReady(); android_camera_start_autofocus(m_service->androidControl()); } AutoFocusMode AalCameraFocusControl::qt2Android(QCameraFocus::FocusModes mode) { switch(mode) { case QCameraFocus::ManualFocus: return AUTO_FOCUS_MODE_OFF; case QCameraFocus::InfinityFocus: return AUTO_FOCUS_MODE_INFINITY; case QCameraFocus::ContinuousFocus: if (m_service->cameraControl()->captureMode() == QCamera::CaptureStillImage) return AUTO_FOCUS_MODE_CONTINUOUS_PICTURE; else return AUTO_FOCUS_MODE_CONTINUOUS_VIDEO; case QCameraFocus::MacroFocus: return AUTO_FOCUS_MODE_MACRO; case QCameraFocus::AutoFocus: case QCameraFocus::HyperfocalFocus: default: return AUTO_FOCUS_MODE_AUTO; } } QCameraFocus::FocusModes AalCameraFocusControl::android2Qt(AutoFocusMode mode) { switch(mode) { case AUTO_FOCUS_MODE_OFF: return QCameraFocus::ManualFocus; case AUTO_FOCUS_MODE_INFINITY: return QCameraFocus::InfinityFocus; case AUTO_FOCUS_MODE_CONTINUOUS_PICTURE: case AUTO_FOCUS_MODE_CONTINUOUS_VIDEO: return QCameraFocus::ContinuousFocus; case AUTO_FOCUS_MODE_MACRO: return QCameraFocus::MacroFocus; case AUTO_FOCUS_MODE_AUTO: default: return QCameraFocus::AutoFocus; } } FocusRegion AalCameraFocusControl::point2Region(const QPointF &point) const { int centerX = (point.x() * (2* focusFullSize)) - focusFullSize; int maxCenterPosition = focusFullSize - focusRegionSize; centerX = std::max(std::min(centerX, maxCenterPosition), -maxCenterPosition); int centerY = (point.y() * (2 * focusFullSize)) - focusFullSize; centerY = std::max(std::min(centerY, maxCenterPosition), -maxCenterPosition); FocusRegion region; region.left = centerX - focusRegionSize; region.right = centerX + focusRegionSize; region.top = centerY - focusRegionSize; region.bottom = centerY + focusRegionSize; region.weight = 5; return region; } ./src/audiocapture.cpp0000644000015600001650000001234012675020550015057 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authored by: Jim Hodapp */ #include "audiocapture.h" #include #include #include #include #include #include AudioCapture::AudioCapture(MediaRecorderWrapper *mediaRecorder) : m_paStream(NULL), m_audioPipe(-1), m_flagExit(false), m_mediaRecorder(mediaRecorder) { } AudioCapture::~AudioCapture() { android_recorder_set_audio_read_cb(m_mediaRecorder, NULL, NULL); if (m_audioPipe >= 0) close(m_audioPipe); if (m_paStream != NULL) pa_simple_free(m_paStream); } /*! * \brief Initializes AudioCapture so that it's ready to read microphone data from Pulseaudio */ bool AudioCapture::init(RecorderReadAudioCallback callback, void *context) { // The MediaRecorderLayer will call method (callback) when it's ready to encode a new audio buffer android_recorder_set_audio_read_cb(m_mediaRecorder, callback, context); return true; } /*! * \brief Stops the microphone data capture thread loop */ void AudioCapture::stopCapture() { qDebug() << __PRETTY_FUNCTION__; m_flagExit = true; } /*! * \brief The main microphone reader/writer loop. Reads from Pulseaudio, writes to named pipe */ void AudioCapture::run() { m_flagExit = false; qDebug() << __PRETTY_FUNCTION__; int bytesWritten = 0, bytesRead = 0; const size_t readSize = sizeof(m_audioBuf); if (!setupPipe()) { qWarning() << "Failed to open /dev/socket/micshm, cannot write data to pipe"; return; } do { bytesRead = readMicrophone(); if (bytesRead > 0) { bytesWritten = writeDataToPipe(); } } while (bytesRead == readSize && bytesWritten == readSize && !m_flagExit); // Make sure that Pulse stops reading the microphone when recording stops if (m_paStream != NULL) { pa_simple_free(m_paStream); m_paStream = NULL; } } /*! * \brief Reads microphone data from Pulseaudio */ int AudioCapture::readMicrophone() { int ret = 0, error = 0; const size_t readSize = sizeof(m_audioBuf); ret = pa_simple_read(m_paStream, m_audioBuf, readSize, &error); if (ret < 0) qWarning() << "Failed to read audio from the microphone: " << pa_strerror(error); else ret = readSize; return ret; } /*! * \brief Sets up the Pulseaudio microphone input channel */ int AudioCapture::setupMicrophoneStream() { // FIXME: Get these parameters more dynamically from the control static const pa_sample_spec ss = { .format = PA_SAMPLE_S16LE, .rate = 48000, .channels = 1 }; int error = 0; m_paStream = pa_simple_new(NULL, "qtubuntu-camera", PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error); if (m_paStream == NULL) { qWarning() << "Failed to open a PulseAudio channel to read the microphone: " << pa_strerror(error); if (error == PA_ERR_TIMEOUT) { return AUDIO_CAPTURE_TIMEOUT_ERROR; } else { return AUDIO_CAPTURE_GENERAL_ERROR; } } return 0; } /*! * \brief Opens the named pipe /dev/socket/micshm for writing mic data to the Android (reader) side */ bool AudioCapture::setupPipe() { if (m_audioPipe >= 0) { qWarning() << "/dev/socket/micshm already opened, not opening twice"; return true; } // Open the named pipe for writing only m_audioPipe = open("/dev/socket/micshm", O_WRONLY); if (m_audioPipe < 0) { qWarning() << "Failed to open audio data pipe /dev/socket/micshm: " << strerror(errno); return false; } return true; } /*! * \brief Writes mic data to the named pipe /dev/socket/micshm */ int AudioCapture::writeDataToPipe() { // Don't open the named pipe twice if (m_audioPipe < 0 && !setupPipe()) { qWarning() << "Failed to open /dev/socket/micshm, cannot write data to pipe"; return 0; } int num = 0; const size_t writeSize = sizeof(m_audioBuf); num = loopWrite(m_audioPipe, m_audioBuf, writeSize); if (num != writeSize) qWarning() << "Failed to write " << num << " bytes to /dev/socket/micshm: " << strerror(errno) << " (" << errno << ")"; return num; } ssize_t AudioCapture::loopWrite(int fd, const void *data, size_t size) { ssize_t ret = 0; while (size > 0) { ssize_t r; if ((r = write(fd, data, size)) < 0) return r; if (r == 0) break; ret += r; data = (const int16_t*) data + r; size -= (size_t) r; } return ret; } ./src/aalvideorenderercontrol.h0000644000015600001650000000354412675020550016761 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALVIDEORENDERERCONTROL_H #define AALVIDEORENDERERCONTROL_H #include #include #include class AalCameraService; struct CameraControl; struct CameraControlListener; class AalVideoRendererControl : public QVideoRendererControl { Q_OBJECT public: AalVideoRendererControl(AalCameraService *service, QObject *parent = 0); ~AalVideoRendererControl(); QAbstractVideoSurface *surface() const; void setSurface(QAbstractVideoSurface *surface); static void updateViewfinderFrameCB(void *context); const QImage &preview() const; void createPreview(); bool isPreviewStarted() const; public Q_SLOTS: void init(CameraControl *control, CameraControlListener *listener); void startPreview(); void stopPreview(); Q_SIGNALS: void surfaceChanged(QAbstractVideoSurface *surface); void previewReady(); private Q_SLOTS: void updateViewfinderFrame(); void onTextureCreated(unsigned int textureID); void onSnapshotTaken(QImage snapshotImage); private: QAbstractVideoSurface *m_surface; AalCameraService *m_service; bool m_viewFinderRunning; bool m_previewStarted; GLuint m_textureId; QImage m_preview; }; #endif ./src/src.pro0000644000015600001650000000277312675020550013210 0ustar jenkinsjenkinsinclude(../coverage.pri) TARGET = aalcamera TEMPLATE = lib CONFIG += plugin QT += concurrent multimedia opengl gui PLUGIN_TYPE = mediaservice target.path += $$[QT_INSTALL_PLUGINS]/$${PLUGIN_TYPE} INSTALLS = target CONFIG += link_pkgconfig PKGCONFIG += exiv2 libqtubuntu-media-signals libmedia libcamera hybris-egl-platform libpulse-simple OTHER_FILES += aalcamera.json HEADERS += \ aalcameracontrol.h \ aalcameraflashcontrol.h \ aalcamerafocuscontrol.h \ aalcameraservice.h \ aalcameraserviceplugin.h \ aalcamerazoomcontrol.h \ aalimagecapturecontrol.h \ aalimageencodercontrol.h \ aalmediarecordercontrol.h \ aalmetadatawritercontrol.h \ aalvideodeviceselectorcontrol.h \ aalvideoencodersettingscontrol.h \ aalvideorenderercontrol.h \ aalviewfindersettingscontrol.h \ aalcamerainfocontrol.h \ audiocapture.h \ aalcameraexposurecontrol.h \ storagemanager.h SOURCES += \ aalcameracontrol.cpp \ aalcameraflashcontrol.cpp \ aalcamerafocuscontrol.cpp \ aalcameraservice.cpp \ aalcameraserviceplugin.cpp \ aalcamerazoomcontrol.cpp \ aalimagecapturecontrol.cpp \ aalimageencodercontrol.cpp \ aalmediarecordercontrol.cpp \ aalmetadatawritercontrol.cpp \ aalvideodeviceselectorcontrol.cpp \ aalvideoencodersettingscontrol.cpp \ aalvideorenderercontrol.cpp \ aalviewfindersettingscontrol.cpp \ aalcamerainfocontrol.cpp \ audiocapture.cpp \ aalcameraexposurecontrol.cpp \ storagemanager.cpp ./src/aalcamera.json0000644000015600001650000000005512675020550014467 0ustar jenkinsjenkins{ "Keys": ["org.qt-project.qt.camera"] } ./src/aalviewfindersettingscontrol.h0000644000015600001650000000363712675020550020052 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALVIEWFINDERSETTINGSCONTROL_H #define AALVIEWFINDERSETTINGSCONTROL_H #include #include #include class AalCameraService; struct CameraControl; struct CameraControlListener; class AalViewfinderSettingsControl : public QCameraViewfinderSettingsControl { public: AalViewfinderSettingsControl(AalCameraService *service, QObject *parent = 0); ~AalViewfinderSettingsControl(); bool isViewfinderParameterSupported(ViewfinderParameter parameter) const ; void setViewfinderParameter(ViewfinderParameter parameter, const QVariant & value); QVariant viewfinderParameter(ViewfinderParameter parameter) const; QSize currentSize() const; const QList &supportedSizes() const; void setAspectRatio(float ratio); void init(CameraControl *control, CameraControlListener *listener); void resetAllSettings(); static void sizeCB(void* ctx, int width, int height); private: void setSize(const QSize &size); QSize chooseOptimalSize(const QList &sizes) const; AalCameraService *m_service; QSize m_currentSize; float m_aspectRatio; int m_currentFPS; mutable QList m_availableSizes; int m_minFPS; int m_maxFPS; }; #endif // AALVIEWFINDERSETTINGSCONTROL_H ./src/aalvideodeviceselectorcontrol.cpp0000644000015600001650000000535712675020550020512 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalvideodeviceselectorcontrol.h" #include "aalcameraservice.h" #include "aalcameracontrol.h" #include "aalimageencodercontrol.h" #include "aalvideoencodersettingscontrol.h" #include "aalviewfindersettingscontrol.h" #include #include #include #include AalVideoDeviceSelectorControl::AalVideoDeviceSelectorControl(AalCameraService *service, QObject *parent) :QVideoDeviceSelectorControl(parent), m_service(service), m_currentDevice(0), m_numberOfCameras(-1) { } int AalVideoDeviceSelectorControl::defaultDevice() const { return m_currentDevice; } int AalVideoDeviceSelectorControl::deviceCount() const { return QCameraInfo::availableCameras().count(); } QString AalVideoDeviceSelectorControl::deviceDescription(int index) const { return QCameraInfo::availableCameras().value(index).description(); } QString AalVideoDeviceSelectorControl::deviceName(int index) const { return QCameraInfo::availableCameras().value(index).deviceName(); } int AalVideoDeviceSelectorControl::selectedDevice() const { return m_currentDevice; } void AalVideoDeviceSelectorControl::setSelectedDevice(int index) { if (index == m_currentDevice) return; if (index < 0 || index >= deviceCount()) { qWarning() << "no valid device selected: " << index; return; } if (m_service->isRecording()) return; m_service->stopPreview(); m_service->disconnectCamera(); m_service->viewfinderControl()->resetAllSettings(); m_service->imageEncoderControl()->resetAllSettings(); m_service->videoEncoderControl()->resetAllSettings(); m_currentDevice = index; QCamera::State state = m_service->cameraControl()->state(); if (state == QCamera::LoadedState) { m_service->connectCamera(); } else if (state == QCamera::ActiveState) { m_service->connectCamera(); m_service->startPreview(); } Q_EMIT selectedDeviceChanged(m_currentDevice); Q_EMIT selectedDeviceChanged(deviceName(m_currentDevice)); } ./src/aalcameracontrol.cpp0000644000015600001650000000730512675020550015706 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameracontrol.h" #include "aalcameraservice.h" #include AalCameraControl::AalCameraControl(AalCameraService *service, QObject *parent) : QCameraControl(parent), m_service(service), m_state(QCamera::UnloadedState), m_status(QCamera::UnloadedStatus), m_captureMode(QCamera::CaptureStillImage) { } AalCameraControl::~AalCameraControl() { } QCamera::State AalCameraControl::state() const { return m_state; } void AalCameraControl::setState(QCamera::State state) { if (m_state == state) return; if (state == QCamera::ActiveState) { bool ok = m_service->connectCamera(); if (!ok) { Q_EMIT error(QCamera::ServiceMissingError, QLatin1String("Unable to connect to camera")); return; } if (m_captureMode == QCamera::CaptureStillImage) { m_service->enablePhotoMode(); } else { m_service->enableVideoMode(); } Q_EMIT captureModeChanged(m_captureMode); m_service->startPreview(); } else if (state == QCamera::LoadedState) { if (m_state == QCamera::UnloadedState) { bool ok = m_service->connectCamera(); if (!ok) { Q_EMIT error(QCamera::ServiceMissingError, QLatin1String("Unable to connect to camera")); return; } } else { m_service->stopPreview(); } } else if (state == QCamera::UnloadedState) { m_service->disconnectCamera(); } m_state = state; Q_EMIT stateChanged(m_state); m_service->updateCaptureReady(); } QCamera::Status AalCameraControl::status() const { return m_status; } QCamera::CaptureModes AalCameraControl::captureMode() const { return m_captureMode; } void AalCameraControl::setCaptureMode(QCamera::CaptureModes mode) { if (m_captureMode == mode) return; if (m_service->isRecording()) return; m_captureMode = mode; if (m_service->androidControl()) { if (mode == QCamera::CaptureStillImage) { m_service->enablePhotoMode(); } else { m_service->enableVideoMode(); } Q_EMIT captureModeChanged(mode); } } bool AalCameraControl::isCaptureModeSupported(QCamera::CaptureModes mode) const { return (QCamera::CaptureStillImage==mode) | (QCamera::CaptureVideo==mode); } bool AalCameraControl::canChangeProperty(QCameraControl::PropertyChangeType changeType, QCamera::Status status) const { Q_UNUSED(changeType); Q_UNUSED(status); return true; } void AalCameraControl::init(CameraControl *control, CameraControlListener *listener) { Q_UNUSED(control); listener->on_msg_error_cb = &AalCameraControl::errorCB; } void AalCameraControl::handleError() { Q_EMIT error(QCamera::CameraError, QLatin1String("Unknown error in camera")); } void AalCameraControl::errorCB(void *context) { Q_UNUSED(context); QMetaObject::invokeMethod(AalCameraService::instance()->cameraControl(), "handleError", Qt::QueuedConnection); } ./src/aalcamerazoomcontrol.cpp0000644000015600001650000000616312675020550016614 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcamerazoomcontrol.h" #include "aalcameracontrol.h" #include "aalcameraservice.h" #include #include #include AalCameraZoomControl::AalCameraZoomControl(AalCameraService *service, QObject *parent) : QCameraZoomControl(parent), m_service(service), m_currentDigitalZoom(0), m_maximumDigitalZoom(1), m_pendingZoom(-1) { } qreal AalCameraZoomControl::currentDigitalZoom() const { return (qreal)m_currentDigitalZoom; } qreal AalCameraZoomControl::currentOpticalZoom() const { return 0.0; } qreal AalCameraZoomControl::maximumDigitalZoom() const { return (qreal)m_maximumDigitalZoom; } qreal AalCameraZoomControl::maximumOpticalZoom() const { return 0.0; } qreal AalCameraZoomControl::requestedDigitalZoom() const { return (qreal)m_pendingZoom; } qreal AalCameraZoomControl::requestedOpticalZoom() const { return 0.0; } void AalCameraZoomControl::zoomTo(qreal optical, qreal digital) { Q_UNUSED(optical); if (!m_service->androidControl()) return; if (digital < 0.0 || digital > m_maximumDigitalZoom) { qWarning() << "Invalid zoom value:" << digital; return; } m_pendingZoom = static_cast(digital); if (m_pendingZoom == m_currentDigitalZoom) return; android_camera_set_zoom(m_service->androidControl(), m_pendingZoom); m_currentDigitalZoom = m_pendingZoom; Q_EMIT currentDigitalZoomChanged(m_currentDigitalZoom); } void AalCameraZoomControl::init(CameraControl *control, CameraControlListener *listener) { Q_UNUSED(control); Q_UNUSED(listener); resetZoom(); } /*! * \brief AalCameraZoomControl::reset sets the current zoom value to 0 and the * maximum zoom value to the maximum zoom level that the hardware reports as * supporting */ void AalCameraZoomControl::resetZoom() { if (!m_service->androidControl()) { return; } if (m_currentDigitalZoom != 0) { m_currentDigitalZoom = 0; Q_EMIT currentDigitalZoomChanged(m_currentDigitalZoom); } android_camera_set_zoom(m_service->androidControl(), m_currentDigitalZoom); int maxValue = 1; android_camera_get_max_zoom(m_service->androidControl(), &maxValue); if (maxValue < 0) { return; } if (maxValue != m_maximumDigitalZoom) { m_maximumDigitalZoom = maxValue; Q_EMIT maximumDigitalZoomChanged(m_maximumDigitalZoom); } } ./src/aalvideoencodersettingscontrol.h0000644000015600001650000000400712675020550020346 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALVIDEOENCODERSETTINGSCONTROL_H #define AALVIDEOENCODERSETTINGSCONTROL_H #include class AalCameraService; struct CameraControl; struct CameraControlListener; class AalVideoEncoderSettingsControl : public QVideoEncoderSettingsControl { Q_OBJECT public: explicit AalVideoEncoderSettingsControl(AalCameraService *service, QObject *parent = 0); virtual void setVideoSettings(const QVideoEncoderSettings &settings); virtual QList supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous = 0) const; virtual QList supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous = 0) const; virtual QStringList supportedVideoCodecs() const; virtual QString videoCodecDescription(const QString &codec) const; virtual QVideoEncoderSettings videoSettings() const; float getAspectRatio() const; void init(CameraControl *control, CameraControlListener *listener); void resetAllSettings(); static void sizeCB(void *ctx, int width, int height); private: void querySupportedResolution() const; AalCameraService *m_service; QVideoEncoderSettings m_settings; mutable QList m_availableSizes; static const QSize DEFAULT_SIZE; static const int DEFAULT_FPS; static const QString DEFAULT_CODEC; }; #endif // AALVIDEOENCODERSETTINGSCONTROL_H ./src/aalcameraflashcontrol.h0000644000015600001650000000335712675020550016374 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALCAMERAFLASHCONTROL_H #define AALCAMERAFLASHCONTROL_H #include #include #include #include class AalCameraService; struct CameraControl; class AalCameraFlashControl : public QCameraFlashControl { Q_OBJECT public: AalCameraFlashControl(AalCameraService *service, QObject *parent = 0); QCameraExposure::FlashModes flashMode() const; bool isFlashModeSupported(QCameraExposure::FlashModes mode) const; bool isFlashReady() const; void setFlashMode(QCameraExposure::FlashModes mode); static void supportedFlashModesCallback(void *context, FlashMode flashMode); public Q_SLOTS: void init(CameraControl *control); private: FlashMode qt2Android(QCameraExposure::FlashModes mode); QCameraExposure::FlashModes android2Qt(FlashMode mode); void querySupportedFlashModes(CameraControl *control); AalCameraService *m_service; QCameraExposure::FlashModes m_currentMode; QSet m_supportedModes; }; #endif // AALCAMERAFLASHCONTROL_H ./src/aalmediarecordercontrol.h0000644000015600001650000000645312675020550016733 0ustar jenkinsjenkins/* * Copyright (C) 2013-2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALMEDIARECORDERCONTROL_H #define AALMEDIARECORDERCONTROL_H #include #include #include #include #include #include class AalCameraService; struct CameraControl; struct CameraControlListener; struct MediaRecorderWrapper; class AudioCapture; class QThread; class QTimer; class AalMediaRecorderControl : public QMediaRecorderControl { Q_OBJECT public: AalMediaRecorderControl(AalCameraService *service, QObject *parent = 0); ~AalMediaRecorderControl(); virtual void applySettings(); virtual qint64 duration() const; virtual bool isMuted() const; virtual QUrl outputLocation() const; virtual bool setOutputLocation(const QUrl & location); virtual QMediaRecorder::State state() const; virtual QMediaRecorder::Status status() const; virtual qreal volume() const; static void errorCB(void* context); void init(CameraControl *control, CameraControlListener *listener); MediaRecorderWrapper* mediaRecorder() const; AudioCapture *audioCapture() const; public Q_SLOTS: virtual void setMuted(bool muted); virtual void setState(QMediaRecorder::State state); virtual void setVolume(qreal gain); void startAudioCaptureThread(); signals: void audioCaptureThreadStarted(); private Q_SLOTS: virtual void updateDuration(); void handleError(); void deleteAudioCapture(); private: bool initRecorder(); void deleteRecorder(); int initAudioCapture(); void setStatus(QMediaRecorder::Status status); int startRecording(); void stopRecording(); void setParameter(const QString ¶meter, int value); static void recorderReadAudioCallback(void *context); AalCameraService *m_service; MediaRecorderWrapper *m_mediaRecorder; AudioCapture *m_audioCapture; int m_outfd; QUrl m_outputLocation; qint64 m_duration; QMediaRecorder::State m_currentState; QMediaRecorder::Status m_currentStatus; QTimer *m_recordingTimer; QThread m_audioCaptureThread; bool m_audioCaptureAvailable; static const int RECORDER_GENERAL_ERROR = -1; static const int RECORDER_NOT_AVAILABLE_ERROR = -2; static const int RECORDER_INITIALIZATION_ERROR = -3; static const int DURATION_UPDATE_INTERVAL = 1000; // update every second static const QLatin1String PARAM_AUDIO_BITRATE; static const QLatin1String PARAM_AUDIO_CHANNELS; static const QLatin1String PARAM_AUTIO_SAMPLING; static const QLatin1String PARAM_LATITUDE; static const QLatin1String PARAM_LONGITUDE; static const QLatin1String PARAM_ORIENTATION; static const QLatin1String PARAM_VIDEO_BITRATE; }; #endif ./src/aalcameraflashcontrol.cpp0000644000015600001650000000653612675020550016731 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameraflashcontrol.h" #include "aalcameracontrol.h" #include "aalcameraservice.h" #include #include #include AalCameraFlashControl::AalCameraFlashControl(AalCameraService *service, QObject *parent) : QCameraFlashControl(parent), m_service(service), m_currentMode(QCameraExposure::FlashManual) { } QCameraExposure::FlashModes AalCameraFlashControl::flashMode() const { return m_currentMode; } bool AalCameraFlashControl::isFlashModeSupported(QCameraExposure::FlashModes mode) const { return m_supportedModes.isEmpty() || m_supportedModes.contains(mode); } bool AalCameraFlashControl::isFlashReady() const { return true; } void AalCameraFlashControl::setFlashMode(QCameraExposure::FlashModes mode) { if (mode == m_currentMode || !isFlashModeSupported(mode)) return; FlashMode fmode = qt2Android(mode); m_currentMode = mode; if (m_service->androidControl()) { android_camera_set_flash_mode(m_service->androidControl(), fmode); } } void AalCameraFlashControl::init(CameraControl *control) { querySupportedFlashModes(control); FlashMode mode = qt2Android(m_currentMode); android_camera_set_flash_mode(control, mode); Q_EMIT flashReady(true); } FlashMode AalCameraFlashControl::qt2Android(QCameraExposure::FlashModes mode) { switch(mode) { case QCameraExposure::FlashOff: return FLASH_MODE_OFF; case QCameraExposure::FlashOn: return FLASH_MODE_ON; case QCameraExposure::FlashVideoLight: case QCameraExposure::FlashTorch: return FLASH_MODE_TORCH; case QCameraExposure::FlashAuto: default: return FLASH_MODE_AUTO; } } QCameraExposure::FlashModes AalCameraFlashControl::android2Qt(FlashMode mode) { switch(mode) { case FLASH_MODE_ON: return QCameraExposure::FlashOn; case FLASH_MODE_TORCH: return QCameraExposure::FlashVideoLight; case FLASH_MODE_AUTO: return QCameraExposure::FlashAuto; case FLASH_MODE_OFF: default: return QCameraExposure::FlashOff; } } /*! * \brief AalCameraFlashControl::querySupportedFlashModes gets the supported * flash modes for the current camera */ void AalCameraFlashControl::querySupportedFlashModes(CameraControl *control) { m_supportedModes.clear(); android_camera_enumerate_supported_flash_modes(control, &AalCameraFlashControl::supportedFlashModesCallback, this); } void AalCameraFlashControl::supportedFlashModesCallback(void *context, FlashMode flashMode) { AalCameraFlashControl *self = (AalCameraFlashControl*)context; self->m_supportedModes << self->android2Qt(flashMode); } ./src/aalimagecapturecontrol.h0000644000015600001650000000477412675020550016600 0ustar jenkinsjenkins/* * Copyright (C) 2013-2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALIMAGECAPTURECONTROL_H #define AALIMAGECAPTURECONTROL_H #include #include #include #include #include #include class AalCameraService; class AalCameraControl; class CameraControl; class CameraControlListener; class QMediaPlayer; typedef QFutureWatcher DiskWriteWatcher; class AalImageCaptureControl : public QCameraImageCaptureControl { Q_OBJECT public: AalImageCaptureControl(AalCameraService *service, QObject *parent = 0); ~AalImageCaptureControl(); int capture(const QString &fileName); void cancelCapture(); bool isReadyForCapture() const; QCameraImageCapture::DriveMode driveMode() const { return QCameraImageCapture::SingleImageCapture; } void setDriveMode(QCameraImageCapture::DriveMode ) {} static void shutterCB(void* context); static void saveJpegCB(void* data, uint32_t data_size, void* context); void setReady(bool ready); bool isCaptureRunning() const; public Q_SLOTS: void init(CameraControl *control, CameraControlListener *listener); void onImageFileSaved(); private Q_SLOTS: void shutter(); void saveJpeg(const QByteArray& data); private: bool updateJpegMetadata(void* data, uint32_t dataSize, QTemporaryFile* destination); AalCameraService *m_service; AalCameraControl *m_cameraControl; int m_lastRequestId; StorageManager m_storageManager; bool m_ready; QString m_targetFileName; bool m_captureCancelled; float m_screenAspectRatio; /// Maintains a list of highest priority aspect ratio to lowest, for the /// currently selected camera QList m_prioritizedAspectRatios; QString m_galleryPath; QMediaPlayer *m_audioPlayer; QSettings m_settings; QMap m_pendingSaveOperations; }; #endif ./src/aalcameracontrol.h0000644000015600001650000000317712675020550015356 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALCAMERACONTROL_H #define AALCAMERACONTROL_H #include class AalCameraService; struct CameraControl; struct CameraControlListener; class AalCameraControl : public QCameraControl { Q_OBJECT public: AalCameraControl(AalCameraService *service, QObject *parent = 0); ~AalCameraControl(); QCamera::State state() const; void setState(QCamera::State state); QCamera::Status status() const; QCamera::CaptureModes captureMode() const; void setCaptureMode(QCamera::CaptureModes); bool isCaptureModeSupported(QCamera::CaptureModes mode) const; bool canChangeProperty(PropertyChangeType changeType, QCamera::Status status) const; static void errorCB(void* context); public Q_SLOTS: void init(CameraControl *control, CameraControlListener *listener); private Q_SLOTS: void handleError(); private: AalCameraService *m_service; QCamera::State m_state; QCamera::Status m_status; QCamera::CaptureModes m_captureMode; }; #endif ./src/aalcamerainfocontrol.h0000644000015600001650000000202012675020550016214 0ustar jenkinsjenkins/* * Copyright (C) 2016 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef AALCAMERAINFOCONTROL_H #define AALCAMERAINFOCONTROL_H #include class AalCameraInfoControl : public QCameraInfoControl { Q_OBJECT public: AalCameraInfoControl(QObject *parent = 0); QCamera::Position cameraPosition(const QString &deviceName) const; int cameraOrientation(const QString &deviceName) const; }; #endif // AALCAMERAINFOCONTROL_H ./COPYING0000644000015600001650000001674312675020550012145 0ustar jenkinsjenkins GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. ./unittests/0000755000015600001650000000000012675020550013141 5ustar jenkinsjenkins./unittests/aalcamerazoomcontrol/0000755000015600001650000000000012675020550017355 5ustar jenkinsjenkins./unittests/aalcamerazoomcontrol/aalcameraservice.cpp0000644000015600001650000000462212675020550023354 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameraservice.h" #include "aalcameracontrol.h" #include #include AalCameraService *AalCameraService::m_service = 0; AalCameraService::AalCameraService(QObject *parent) : QMediaService(parent), m_androidControl(0), m_androidListener(0) { m_cameraControl = new AalCameraControl(this); m_zoomControl = new AalCameraZoomControl(this); } AalCameraService::~AalCameraService() { delete m_cameraControl; delete m_zoomControl; } QMediaControl *AalCameraService::requestControl(const char *name) { Q_UNUSED(name); return 0; } void AalCameraService::releaseControl(QMediaControl *control) { Q_UNUSED(control); } CameraControl *AalCameraService::androidControl() { return m_androidControl; } bool AalCameraService::connectCamera() { m_androidListener = new CameraControlListener; m_androidControl = android_camera_connect_to(BACK_FACING_CAMERA_TYPE, m_androidListener); initControls(m_androidControl, m_androidListener); return true; } void AalCameraService::disconnectCamera() { delete m_androidListener; android_camera_disconnect(m_androidControl); } void AalCameraService::startPreview() { } void AalCameraService::stopPreview() { } bool AalCameraService::isPreviewStarted() const { return true; } void AalCameraService::onApplicationStateChanged() { } void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener) { m_zoomControl->init(camControl, listener); } void AalCameraService::updateCaptureReady() { } QSize AalCameraService::selectSizeWithAspectRatio(const QList &sizes, float targetAspectRatio) const { Q_UNUSED(sizes); Q_UNUSED(targetAspectRatio); return QSize(); } ./unittests/aalcamerazoomcontrol/aalcamerazoomcontrol.pro0000644000015600001650000000102312675020550024307 0ustar jenkinsjenkinsinclude(../../coverage.pri) TARGET = tst_aalcamerazoomcontrol QT += testlib multimedia opengl LIBS += -L../mocks/aal -laal INCLUDEPATH += ../../src INCLUDEPATH += ../mocks/aal HEADERS += ../../src/aalcamerazoomcontrol.h \ ../../src/aalcameracontrol.h \ ../../src/aalcameraservice.h SOURCES += tst_aalcamerazoomcontrol.cpp \ ../../src/aalcamerazoomcontrol.cpp \ ../stubs/aalcameracontrol_stub.cpp \ aalcameraservice.cpp check.depends = $${TARGET} check.commands = ./$${TARGET} QMAKE_EXTRA_TARGETS += check ./unittests/aalcamerazoomcontrol/tst_aalcamerazoomcontrol.cpp0000644000015600001650000000353612675020550025176 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include "aalcameraservice.h" #define private public #include "aalcamerazoomcontrol.h" class tst_AalCameraZoomControl : public QObject { Q_OBJECT private slots: void initTestCase(); void cleanupTestCase(); void zoomTo(); private: AalCameraZoomControl *m_zoomControl; AalCameraService *m_service; }; void tst_AalCameraZoomControl::initTestCase() { m_service = new AalCameraService(); m_zoomControl = m_service->zoomControl(); } void tst_AalCameraZoomControl::cleanupTestCase() { delete m_service; } void tst_AalCameraZoomControl::zoomTo() { QSignalSpy spy(m_zoomControl, SIGNAL(currentDigitalZoomChanged(qreal))); int zoom = 3.0; m_zoomControl->zoomTo(0.0, zoom); QCOMPARE(m_zoomControl->currentDigitalZoom(), 0.0); QCOMPARE(spy.count(), 0); m_service->connectCamera(); zoom = 3.0; m_zoomControl->zoomTo(0.0, zoom); QCOMPARE(m_zoomControl->currentDigitalZoom(), 3.0); QCOMPARE(spy.count(), 1); m_zoomControl->resetZoom(); QCOMPARE(m_zoomControl->currentDigitalZoom(), 0.0); QCOMPARE(spy.count(), 2); } QTEST_GUILESS_MAIN(tst_AalCameraZoomControl) #include "tst_aalcamerazoomcontrol.moc" ./unittests/unittests.pro0000644000015600001650000000050612675020550015726 0ustar jenkinsjenkinsinclude(../coverage.pri) TEMPLATE = subdirs SUBDIRS += \ mocks \ aalcameracontrol \ aalcameraexposurecontrol \ aalcameraflashcontrol \ aalcamerafocuscontrol \ aalcamerazoomcontrol \ aalmediarecordercontrol \ aalvideodeviceselectorcontrol \ aalviewfindersettingscontrol \ storagemanager ./unittests/aalcameraflashcontrol/0000755000015600001650000000000012675020550017466 5ustar jenkinsjenkins./unittests/aalcameraflashcontrol/aalcameraflashcontrol.pro0000644000015600001650000000102712675020550024535 0ustar jenkinsjenkinsinclude(../../coverage.pri) TARGET = tst_aalcameraflashcontrol QT += testlib multimedia opengl LIBS += -L../mocks/aal -laal INCLUDEPATH += ../../src INCLUDEPATH += ../mocks/aal HEADERS += ../../src/aalcameraflashcontrol.h \ ../../src/aalcameracontrol.h \ ../../src/aalcameraservice.h SOURCES += tst_aalcameraflashcontrol.cpp \ ../../src/aalcameraflashcontrol.cpp \ ../stubs/aalcameracontrol_stub.cpp \ aalcameraservice.cpp check.depends = $${TARGET} check.commands = ./$${TARGET} QMAKE_EXTRA_TARGETS += check ./unittests/aalcameraflashcontrol/aalcameraservice.cpp0000644000015600001650000000414012675020550023460 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameraservice.h" #include "aalcameracontrol.h" AalCameraService *AalCameraService::m_service = 0; AalCameraService::AalCameraService(QObject *parent) : QMediaService(parent), m_androidControl(0), m_androidListener(0) { m_cameraControl = new AalCameraControl(this); } AalCameraService::~AalCameraService() { delete m_cameraControl; } QMediaControl *AalCameraService::requestControl(const char *name) { Q_UNUSED(name); return 0; } void AalCameraService::releaseControl(QMediaControl *control) { Q_UNUSED(control); } CameraControl *AalCameraService::androidControl() { return m_androidControl; } bool AalCameraService::connectCamera() { return true; } void AalCameraService::disconnectCamera() { } void AalCameraService::startPreview() { } void AalCameraService::stopPreview() { } bool AalCameraService::isPreviewStarted() const { return true; } void AalCameraService::onApplicationStateChanged() { } void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener) { Q_UNUSED(camControl); Q_UNUSED(listener); } bool AalCameraService::isCameraActive() const { return true; } bool AalCameraService::isBackCameraUsed() const { return true; } void AalCameraService::updateCaptureReady() { } QSize AalCameraService::selectSizeWithAspectRatio(const QList &sizes, float targetAspectRatio) const { Q_UNUSED(sizes); Q_UNUSED(targetAspectRatio); return QSize(); } ./unittests/aalcameraflashcontrol/tst_aalcameraflashcontrol.cpp0000644000015600001650000000317012675020550025412 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include "aalcameraservice.h" #define private public #include "aalcameraflashcontrol.h" class tst_AalCameraFlashControl : public QObject { Q_OBJECT private slots: void initTestCase(); void cleanupTestCase(); void flashMode(); private: AalCameraFlashControl *m_flashControl; AalCameraService *m_service; }; void tst_AalCameraFlashControl::initTestCase() { m_service = new AalCameraService(); m_flashControl = new AalCameraFlashControl(m_service); } void tst_AalCameraFlashControl::cleanupTestCase() { delete m_flashControl; delete m_service; } void tst_AalCameraFlashControl::flashMode() { m_flashControl->m_supportedModes << QCameraExposure::FlashOff << QCameraExposure::FlashOn; QCameraExposure::FlashModes mode = QCameraExposure::FlashOn; m_flashControl->setFlashMode(mode); QCOMPARE(m_flashControl->flashMode(), mode); } QTEST_GUILESS_MAIN(tst_AalCameraFlashControl) #include "tst_aalcameraflashcontrol.moc" ./unittests/aalvideodeviceselectorcontrol/0000755000015600001650000000000012675020550021247 5ustar jenkinsjenkins./unittests/aalvideodeviceselectorcontrol/aalcameraservice.cpp0000644000015600001650000000413412675020550025244 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameraservice.h" #include "aalcameracontrol.h" AalCameraService *AalCameraService::m_service = 0; AalCameraService::AalCameraService(QObject *parent) : QMediaService(parent), m_androidControl(0), m_androidListener(0) { m_cameraControl = new AalCameraControl(this); } AalCameraService::~AalCameraService() { delete m_cameraControl; } QMediaControl *AalCameraService::requestControl(const char *name) { Q_UNUSED(name); return 0; } void AalCameraService::releaseControl(QMediaControl *control) { Q_UNUSED(control); } CameraControl *AalCameraService::androidControl() { return m_androidControl; } bool AalCameraService::connectCamera() { return true; } void AalCameraService::disconnectCamera() { } void AalCameraService::startPreview() { } void AalCameraService::stopPreview() { } bool AalCameraService::isPreviewStarted() const { return true; } bool AalCameraService::isCameraActive() const { return true; } void AalCameraService::onApplicationStateChanged() { } void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener) { Q_UNUSED(camControl); Q_UNUSED(listener); } bool AalCameraService::isRecording() const { return false; } void AalCameraService::updateCaptureReady() { } QSize AalCameraService::selectSizeWithAspectRatio(const QList &sizes, float targetAspectRatio) const { Q_UNUSED(sizes); Q_UNUSED(targetAspectRatio); return QSize(); } ./unittests/aalvideodeviceselectorcontrol/aalimageencodercontrol.cpp0000644000015600001650000000450212675020550026455 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalimageencodercontrol.h" #include "aalcameraservice.h" AalImageEncoderControl::AalImageEncoderControl(AalCameraService *service, QObject *parent) : QImageEncoderControl(parent), m_service(service), m_currentSize() { } AalImageEncoderControl::~AalImageEncoderControl() { } QString AalImageEncoderControl::imageCodecDescription(const QString &codec) const { Q_UNUSED(codec); return QString(); } QImageEncoderSettings AalImageEncoderControl::imageSettings() const { return QImageEncoderSettings(); } void AalImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings) { Q_UNUSED(settings); } QStringList AalImageEncoderControl::supportedImageCodecs() const { return QStringList(); } QList AalImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const { Q_UNUSED(settings); Q_UNUSED(continuous); return QList(); } void AalImageEncoderControl::init(CameraControl *control) { Q_UNUSED(control); } bool AalImageEncoderControl::setSize(const QSize &size) { Q_UNUSED(size); return true; } void AalImageEncoderControl::resetAllSettings() { } void AalImageEncoderControl::getPictureSizeCb(void *ctx, int width, int height) { Q_UNUSED(ctx); Q_UNUSED(width); Q_UNUSED(height); } void AalImageEncoderControl::getPictureSize(int width, int height) { Q_UNUSED(width); Q_UNUSED(height); } void AalImageEncoderControl::getThumbnailSizeCb(void *ctx, int width, int height) { Q_UNUSED(ctx); Q_UNUSED(width); Q_UNUSED(height); } void AalImageEncoderControl::getThumbnailSize(int width, int height) { Q_UNUSED(width); Q_UNUSED(height); } ./unittests/aalvideodeviceselectorcontrol/aalviewfindersettingscontrol.cpp0000644000015600001650000000305412675020550027757 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalviewfindersettingscontrol.h" #include "aalcameraservice.h" AalViewfinderSettingsControl::AalViewfinderSettingsControl(AalCameraService *service, QObject *parent) :QCameraViewfinderSettingsControl(parent), m_service(service), m_currentSize(), m_currentFPS(30), m_minFPS(10), m_maxFPS(30) { } AalViewfinderSettingsControl::~AalViewfinderSettingsControl() { } bool AalViewfinderSettingsControl::isViewfinderParameterSupported(ViewfinderParameter parameter) const { Q_UNUSED(parameter); return false; } void AalViewfinderSettingsControl::setViewfinderParameter(ViewfinderParameter parameter, const QVariant &value) { Q_UNUSED(parameter); Q_UNUSED(value); } QVariant AalViewfinderSettingsControl::viewfinderParameter(ViewfinderParameter parameter) const { Q_UNUSED(parameter); return QVariant(); } void AalViewfinderSettingsControl::resetAllSettings() { } ./unittests/aalvideodeviceselectorcontrol/aalvideodeviceselectorcontrol.pro0000644000015600001650000000155012675020550030100 0ustar jenkinsjenkinsinclude(../../coverage.pri) TARGET = tst_aalvideodeviceselectorcontrol QT += testlib multimedia opengl LIBS += -L../mocks/aal -laal INCLUDEPATH += ../../src INCLUDEPATH += ../mocks/aal INCLUDEPATH += ../stubs/ HEADERS += ../../src/aalvideodeviceselectorcontrol.h \ ../../src/aalcameracontrol.h \ ../../src/aalcameraservice.h \ ../../src/aalvideoencodersettingscontrol.h \ ../stubs/qcamerainfodata.h SOURCES += tst_aalvideodeviceselectorcontrol.cpp \ ../../src/aalvideodeviceselectorcontrol.cpp \ aalcameraservice.cpp \ aalimageencodercontrol.cpp \ aalviewfindersettingscontrol.cpp \ ../stubs/aalcameracontrol_stub.cpp \ ../stubs/aalvideoencodersettingscontrol_stub.cpp \ ../stubs/qcamerainfo_stub.cpp \ ../stubs/qcamerainfodata.cpp check.depends = $${TARGET} check.commands = ./$${TARGET} QMAKE_EXTRA_TARGETS += check ./unittests/aalvideodeviceselectorcontrol/tst_aalvideodeviceselectorcontrol.cpp0000644000015600001650000000377412675020550030766 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include "aalcameraservice.h" #define private public #include "aalvideodeviceselectorcontrol.h" #include "qcamerainfodata.h" class tst_AalVideoDeviceSelectorControl : public QObject { Q_OBJECT private slots: void initTestCase(); void cleanupTestCase(); void selectDevice(); private: AalVideoDeviceSelectorControl *m_selectControl; AalCameraService *m_service; }; void tst_AalVideoDeviceSelectorControl::initTestCase() { m_service = new AalCameraService(); m_selectControl = new AalVideoDeviceSelectorControl(m_service); } void tst_AalVideoDeviceSelectorControl::cleanupTestCase() { delete m_selectControl; delete m_service; } void tst_AalVideoDeviceSelectorControl::selectDevice() { QSignalSpy spy(m_selectControl, SIGNAL(selectedDeviceChanged(int))); QSignalSpy spy2(m_selectControl, SIGNAL(selectedDeviceChanged(QString))); QCameraInfoData::availableDevices.clear(); QCameraInfoData::availableDevices.append(CameraInfo("0", "Camera 0")); QCameraInfoData::availableDevices.append(CameraInfo("1", "Camera 1")); m_selectControl->setSelectedDevice(1); QCOMPARE(m_selectControl->selectedDevice(), 1); QCOMPARE(spy.count(), 1); QCOMPARE(spy2.count(), 1); } QTEST_GUILESS_MAIN(tst_AalVideoDeviceSelectorControl) #include "tst_aalvideodeviceselectorcontrol.moc" ./unittests/aalviewfindersettingscontrol/0000755000015600001650000000000012675020550021143 5ustar jenkinsjenkins./unittests/aalviewfindersettingscontrol/aalcameraservice.cpp0000644000015600001650000000525612675020550025146 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameraservice.h" #include AalCameraService *AalCameraService::m_service = 0; AalCameraService::AalCameraService(QObject *parent) : QMediaService(parent), m_androidControl(0), m_androidListener(0) { } AalCameraService::~AalCameraService() { } QMediaControl *AalCameraService::requestControl(const char *name) { Q_UNUSED(name); return 0; } void AalCameraService::releaseControl(QMediaControl *control) { Q_UNUSED(control); } CameraControl *AalCameraService::androidControl() { return m_androidControl; } bool AalCameraService::connectCamera() { return true; } void AalCameraService::disconnectCamera() { } void AalCameraService::startPreview() { } void AalCameraService::stopPreview() { } bool AalCameraService::isPreviewStarted() const { return true; } void AalCameraService::onApplicationStateChanged() { } void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener) { Q_UNUSED(camControl); Q_UNUSED(listener); } bool AalCameraService::isCameraActive() const { return true; } bool AalCameraService::isBackCameraUsed() const { return true; } void AalCameraService::updateCaptureReady() { } QSize AalCameraService::selectSizeWithAspectRatio(const QList &sizes, float targetAspectRatio) const { QSize selectedSize; long selectedPixelCount = 0; const float EPSILON = 0.02; if (!sizes.empty()) { // Loop over all sizes until we find the highest one that matches targetAspectRatio. QList::const_iterator it = sizes.begin(); while (it != sizes.end()) { QSize size = *it; const float aspectRatio = (float)size.width() / (float)size.height(); const long pixelCount = (long)size.width() * (long)size.height(); if (fabs(aspectRatio - targetAspectRatio) < EPSILON && pixelCount > selectedPixelCount) { selectedSize = size; selectedPixelCount = pixelCount; } ++it; } } return selectedSize; } ./unittests/aalviewfindersettingscontrol/aalvideorenderercontrol.cpp0000644000015600001650000000336512675020550026572 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalvideorenderercontrol.h" #include "aalcameraservice.h" AalVideoRendererControl::AalVideoRendererControl(AalCameraService *service, QObject *parent) : QVideoRendererControl(parent) , m_surface(0), m_service(service), m_viewFinderRunning(false), m_textureId(0) { } AalVideoRendererControl::~AalVideoRendererControl() { } QAbstractVideoSurface *AalVideoRendererControl::surface() const { return m_surface; } void AalVideoRendererControl::setSurface(QAbstractVideoSurface *surface) { Q_UNUSED(surface); } void AalVideoRendererControl::init(CameraControl *control, CameraControlListener *listener) { Q_UNUSED(control); Q_UNUSED(listener); } void AalVideoRendererControl::startPreview() { } void AalVideoRendererControl::stopPreview() { } bool AalVideoRendererControl::isPreviewStarted() const { return true; } void AalVideoRendererControl::updateViewfinderFrame() { } void AalVideoRendererControl::onTextureCreated(unsigned int textureID) { Q_UNUSED(textureID); } void AalVideoRendererControl::onSnapshotTaken(QImage snapshotImage) { Q_UNUSED(snapshotImage); } ./unittests/aalviewfindersettingscontrol/tst_aalviewfindersettingscontrol.cpp0000644000015600001650000000730612675020550030551 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include "aalcameraservice.h" #define private public #include "aalviewfindersettingscontrol.h" class tst_AalViewfinderSettingsControl : public QObject { Q_OBJECT private slots: void initTestCase(); void cleanupTestCase(); void setSize(); void resetAllSettings(); void chooseOptimalSize16by9(); void chooseOptimalSize4by3(); void chooseOptimalSizeEmpty(); void chooseOptimalSize0AspectRatio(); void chooseOptimalSize0AspectRatioEmpty(); private: AalViewfinderSettingsControl *m_vfControl; AalCameraService *m_service; friend class AalViewfinderSettingsControl; }; void tst_AalViewfinderSettingsControl::initTestCase() { m_service = new AalCameraService(); m_vfControl = new AalViewfinderSettingsControl(m_service); } void tst_AalViewfinderSettingsControl::cleanupTestCase() { delete m_vfControl; delete m_service; } void tst_AalViewfinderSettingsControl::setSize() { m_vfControl->m_currentSize = QSize(123, 234); QSize size(640, 480); m_vfControl->setViewfinderParameter(QCameraViewfinderSettingsControl::Resolution, size); QSize result = m_vfControl->viewfinderParameter(QCameraViewfinderSettingsControl::Resolution).toSize(); QCOMPARE(result, size); QCOMPARE(result, m_vfControl->currentSize()); } void tst_AalViewfinderSettingsControl::resetAllSettings() { m_vfControl->m_currentSize = QSize(123, 234); m_vfControl->resetAllSettings(); QCOMPARE(m_vfControl->currentSize(), QSize()); } void tst_AalViewfinderSettingsControl::chooseOptimalSize16by9() { m_vfControl->m_aspectRatio = (float)16 / (float)9; QList resolutions; resolutions.append(QSize(1920, 1080)); resolutions.append(QSize(1280, 720)); resolutions.append(QSize(960, 720)); QCOMPARE(m_vfControl->chooseOptimalSize(resolutions), QSize(1920, 1080)); } void tst_AalViewfinderSettingsControl::chooseOptimalSize4by3() { m_vfControl->m_aspectRatio = (float)4 / (float)3; QList resolutions; resolutions.append(QSize(1920, 1080)); resolutions.append(QSize(1280, 720)); resolutions.append(QSize(960, 720)); QCOMPARE(m_vfControl->chooseOptimalSize(resolutions), QSize(960, 720)); } void tst_AalViewfinderSettingsControl::chooseOptimalSizeEmpty() { m_vfControl->m_aspectRatio = (float)4 / (float)3; QList resolutions; QCOMPARE(m_vfControl->chooseOptimalSize(resolutions), QSize()); } void tst_AalViewfinderSettingsControl::chooseOptimalSize0AspectRatio() { m_vfControl->m_aspectRatio = 0; QList resolutions; resolutions.append(QSize(1920, 1080)); resolutions.append(QSize(1280, 720)); resolutions.append(QSize(960, 720)); QCOMPARE(m_vfControl->chooseOptimalSize(resolutions), QSize(1280, 720)); } void tst_AalViewfinderSettingsControl::chooseOptimalSize0AspectRatioEmpty() { m_vfControl->m_aspectRatio = 0; QList resolutions; QCOMPARE(m_vfControl->chooseOptimalSize(resolutions), QSize()); } QTEST_GUILESS_MAIN(tst_AalViewfinderSettingsControl) #include "tst_aalviewfindersettingscontrol.moc" ./unittests/aalviewfindersettingscontrol/aalviewfindersettingscontrol.pro0000644000015600001650000000106312675020550027667 0ustar jenkinsjenkinsinclude(../../coverage.pri) TARGET = tst_aalviewfindersettingscontrol QT += testlib multimedia opengl LIBS += -L../mocks/aal -laal INCLUDEPATH += ../../src INCLUDEPATH += ../mocks/aal HEADERS += ../../src/aalviewfindersettingscontrol.h \ ../../src/aalcameraservice.h \ ../../src/aalvideorenderercontrol.h SOURCES += tst_aalviewfindersettingscontrol.cpp \ ../../src/aalviewfindersettingscontrol.cpp \ aalcameraservice.cpp \ aalvideorenderercontrol.cpp check.depends = $${TARGET} check.commands = ./$${TARGET} QMAKE_EXTRA_TARGETS += check ./unittests/mocks/0000755000015600001650000000000012675020550014255 5ustar jenkinsjenkins./unittests/mocks/mocks.pro0000644000015600001650000000010412675020550016106 0ustar jenkinsjenkinsinclude(../../coverage.pri) TEMPLATE = subdirs SUBDIRS += \ aal ./unittests/mocks/aal/0000755000015600001650000000000012675020550015012 5ustar jenkinsjenkins./unittests/mocks/aal/camera_compatibility_layer_capabilities.h0000644000015600001650000001246412675020550025260 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authored by: Thomas Voss */ #ifndef CAMERA_COMPATIBILITY_LAYER_CONFIGURATION_H_ #define CAMERA_COMPATIBILITY_LAYER_CONFIGURATION_H_ #ifdef __cplusplus extern "C" { #endif struct CameraControl; typedef enum { FLASH_MODE_OFF, FLASH_MODE_AUTO, FLASH_MODE_ON, FLASH_MODE_TORCH } FlashMode; typedef enum { WHITE_BALANCE_MODE_AUTO, WHITE_BALANCE_MODE_DAYLIGHT, WHITE_BALANCE_MODE_CLOUDY_DAYLIGHT, WHITE_BALANCE_MODE_FLUORESCENT, WHITE_BALANCE_MODE_INCANDESCENT } WhiteBalanceMode; typedef enum { SCENE_MODE_AUTO, SCENE_MODE_ACTION, SCENE_MODE_NIGHT, SCENE_MODE_PARTY, SCENE_MODE_SUNSET, SCENE_MODE_HDR } SceneMode; typedef enum { AUTO_FOCUS_MODE_OFF, AUTO_FOCUS_MODE_CONTINUOUS_VIDEO, AUTO_FOCUS_MODE_AUTO, AUTO_FOCUS_MODE_MACRO, AUTO_FOCUS_MODE_CONTINUOUS_PICTURE, AUTO_FOCUS_MODE_INFINITY } AutoFocusMode; typedef enum { EFFECT_MODE_NONE, EFFECT_MODE_MONO, EFFECT_MODE_NEGATIVE, EFFECT_MODE_SOLARIZE, EFFECT_MODE_SEPIA, EFFECT_MODE_POSTERIZE, EFFECT_MODE_WHITEBOARD, EFFECT_MODE_BLACKBOARD, EFFECT_MODE_AQUA } EffectMode; typedef enum { CAMERA_PIXEL_FORMAT_YUV422SP, CAMERA_PIXEL_FORMAT_YUV420SP, CAMERA_PIXEL_FORMAT_YUV422I, CAMERA_PIXEL_FORMAT_YUV420P, CAMERA_PIXEL_FORMAT_RGB565, CAMERA_PIXEL_FORMAT_RGBA8888, CAMERA_PIXEL_FORMAT_BAYER_RGGB } CameraPixelFormat; typedef struct { int top; int left; int bottom; int right; int weight; } FocusRegion; typedef void (*size_callback)(void* ctx, int width, int height); typedef void (*scene_mode_callback)(void* ctx, SceneMode mode); typedef void (*flash_mode_callback)(void* ctx, FlashMode mode); // Dumps the camera parameters to stdout. void android_camera_dump_parameters(CameraControl* control); // Query camera parameters int android_camera_get_number_of_devices(); void android_camera_enumerate_supported_preview_sizes(CameraControl* control, size_callback cb, void* ctx); void android_camera_get_preview_fps_range(CameraControl* control, int* min, int* max); void android_camera_get_preview_fps(CameraControl* control, int* fps); void android_camera_enumerate_supported_picture_sizes(CameraControl* control, size_callback cb, void* ctx); void android_camera_get_preview_size(CameraControl* control, int* width, int* height); void android_camera_get_picture_size(CameraControl* control, int* width, int* height); void android_camera_get_current_zoom(CameraControl* control, int* zoom); void android_camera_get_max_zoom(CameraControl* control, int* max_zoom); void android_camera_get_effect_mode(CameraControl* control, EffectMode* mode); void android_camera_get_flash_mode(CameraControl* control, FlashMode* mode); void android_camera_enumerate_supported_flash_modes(CameraControl* control, flash_mode_callback cb, void* ctx); void android_camera_get_white_balance_mode(CameraControl* control, WhiteBalanceMode* mode); void android_camera_enumerate_supported_scene_modes(CameraControl* control, scene_mode_callback cb, void* ctx); void android_camera_get_scene_mode(CameraControl* control, SceneMode* mode); void android_camera_get_auto_focus_mode(CameraControl* control, AutoFocusMode* mode); void android_camera_get_preview_format(CameraControl* control, CameraPixelFormat* format); void android_camera_get_jpeg_quality(struct CameraControl* control, int* quality); // Adjusts camera parameters void android_camera_set_preview_size(CameraControl* control, int width, int height); void android_camera_set_preview_fps(CameraControl* control, int fps); void android_camera_set_picture_size(CameraControl* control, int width, int height); void android_camera_set_effect_mode(CameraControl* control, EffectMode mode); void android_camera_set_flash_mode(CameraControl* control, FlashMode mode); void android_camera_set_white_balance_mode(CameraControl* control, WhiteBalanceMode mode); void android_camera_set_scene_mode(CameraControl* control, SceneMode mode); void android_camera_set_auto_focus_mode(CameraControl* control, AutoFocusMode mode); void android_camera_set_preview_format(CameraControl* control, CameraPixelFormat format); void android_camera_set_jpeg_quality(struct CameraControl* control, int quality); void android_camera_set_focus_region(CameraControl* control, FocusRegion* region); void android_camera_reset_focus_region(CameraControl* control); // Set photo metadata void android_camera_set_rotation(CameraControl* control, int rotation); void android_camera_set_location(CameraControl* control, const float* latitude, const float* longitude, const float* altitude, int timestamp, const char* method); #ifdef __cplusplus } #endif #endif // CAMERA_COMPATIBILITY_LAYER_CONFIGURATION_H_ ./unittests/mocks/aal/media_recorder_layer.cpp0000644000015600001650000000624612675020550021666 0ustar jenkinsjenkins/* * Copyright © 2013 Canonical Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "media_recorder_layer.h" #include "camera_control.h" #include class MediaRecorderListenerWrapper { public: MediaRecorderListenerWrapper() { } }; struct MediaRecorderWrapper { public: MediaRecorderWrapper() { } }; void android_recorder_set_error_cb(MediaRecorderWrapper *mr, on_recorder_msg_error cb, void *context) { Q_UNUSED(mr); Q_UNUSED(cb); Q_UNUSED(context); } MediaRecorderWrapper *android_media_new_recorder() { MediaRecorderWrapper *mr = new MediaRecorderWrapper; return mr; } int android_recorder_initCheck(MediaRecorderWrapper *mr) { Q_UNUSED(mr); return 0; } int android_recorder_setCamera(MediaRecorderWrapper *mr, CameraControl* control) { Q_UNUSED(mr); Q_UNUSED(control); return 0; } int android_recorder_setVideoSource(MediaRecorderWrapper *mr, VideoSource vs) { Q_UNUSED(mr); Q_UNUSED(vs); return 0; } int android_recorder_setAudioSource(MediaRecorderWrapper *mr, AudioSource as) { Q_UNUSED(mr); Q_UNUSED(as); return 0; } int android_recorder_setOutputFormat(MediaRecorderWrapper *mr, OutputFormat of) { Q_UNUSED(mr); Q_UNUSED(of); return 0; } int android_recorder_setVideoEncoder(MediaRecorderWrapper *mr, VideoEncoder ve) { Q_UNUSED(mr); Q_UNUSED(ve); return 0; } int android_recorder_setAudioEncoder(MediaRecorderWrapper *mr, AudioEncoder ae) { Q_UNUSED(mr); Q_UNUSED(ae); return 0; } int android_recorder_setOutputFile(MediaRecorderWrapper *mr, int fd) { Q_UNUSED(mr); Q_UNUSED(fd); return 0; } int android_recorder_setVideoSize(MediaRecorderWrapper *mr, int width, int height) { Q_UNUSED(mr); Q_UNUSED(width); Q_UNUSED(height); return 0; } int android_recorder_setVideoFrameRate(MediaRecorderWrapper *mr, int frames_per_second) { Q_UNUSED(mr); Q_UNUSED(frames_per_second); return 0; } int android_recorder_setParameters(MediaRecorderWrapper *mr, const char* parameters) { Q_UNUSED(mr); Q_UNUSED(parameters); return 0; } int android_recorder_start(MediaRecorderWrapper *mr) { Q_UNUSED(mr); return 0; } int android_recorder_stop(MediaRecorderWrapper *mr) { Q_UNUSED(mr); return 0; } int android_recorder_prepare(MediaRecorderWrapper *mr) { Q_UNUSED(mr); return 0; } int android_recorder_reset(MediaRecorderWrapper *mr) { Q_UNUSED(mr); return 0; } int android_recorder_close(MediaRecorderWrapper *mr) { Q_UNUSED(mr); return 0; } int android_recorder_release(MediaRecorderWrapper *mr) { Q_UNUSED(mr); return 0; } ./unittests/mocks/aal/aal.pro0000644000015600001650000000050212675020550016266 0ustar jenkinsjenkinsinclude(../../../coverage.pri) TEMPLATE = lib TARGET = aal CONFIG += staticlib HEADERS = camera_compatibility_layer.h \ camera_compatibility_layer_capabilities.h \ camera_control.h \ media_recorder_layer.h SOURCES += camera_compatibility_layer.cpp \ media_recorder_layer.cpp ./unittests/mocks/aal/camera_compatibility_layer.cpp0000644000015600001650000001613212675020550023076 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Authored by: Thomas Voss */ #include "camera_compatibility_layer.h" #include "camera_compatibility_layer_capabilities.h" #include "camera_control.h" #include #include void crashTest(CameraControl* control) { if (control->listener == 0) qDebug() << "Something is wrong, but at least it did not crash"; } int android_camera_get_number_of_devices() { return 2; } CameraControl* android_camera_connect_to(CameraType camera_type, CameraControlListener* listener) { Q_UNUSED(camera_type); CameraControl* cc = new CameraControl(); cc->listener = listener; return cc; } void android_camera_disconnect(CameraControl* control) { crashTest(control); } int android_camera_lock(CameraControl* control) { Q_UNUSED(control); return 0; } int android_camera_unlock(CameraControl* control) { Q_UNUSED(control); return 0; } void android_camera_delete(CameraControl* control) { delete control; } void android_camera_dump_parameters(CameraControl* control) { crashTest(control); } void android_camera_set_flash_mode(CameraControl* control, FlashMode mode) { Q_UNUSED(mode); crashTest(control); } void android_camera_get_flash_mode(CameraControl* control, FlashMode* mode) { Q_UNUSED(mode); crashTest(control); } void android_camera_set_white_balance_mode(CameraControl* control, WhiteBalanceMode mode) { Q_UNUSED(mode); crashTest(control); } void android_camera_get_white_balance_mode(CameraControl* control, WhiteBalanceMode* mode) { Q_UNUSED(mode); crashTest(control); } void android_camera_enumerate_supported_scene_modes(CameraControl* control, scene_mode_callback cb, void* ctx) { Q_UNUSED(cb); Q_UNUSED(ctx); crashTest(control); cb(ctx, SCENE_MODE_ACTION); } void android_camera_enumerate_supported_flash_modes(CameraControl* control, flash_mode_callback cb, void* ctx) { Q_UNUSED(cb); Q_UNUSED(ctx); crashTest(control); cb(ctx, FLASH_MODE_ON); cb(ctx, FLASH_MODE_AUTO); cb(ctx, FLASH_MODE_TORCH); cb(ctx, FLASH_MODE_OFF); } void android_camera_set_scene_mode(CameraControl* control, SceneMode mode) { Q_UNUSED(mode); crashTest(control); } void android_camera_get_scene_mode(CameraControl* control, SceneMode* mode) { Q_UNUSED(mode); crashTest(control); } void android_camera_set_auto_focus_mode(CameraControl* control, AutoFocusMode mode) { Q_UNUSED(mode); crashTest(control); } void android_camera_get_auto_focus_mode(CameraControl* control, AutoFocusMode* mode) { crashTest(control); *mode = AUTO_FOCUS_MODE_AUTO; } void android_camera_set_jpeg_quality(CameraControl* control, int quality) { Q_UNUSED(quality); crashTest(control); } void android_camera_get_jpeg_quality(CameraControl* control, int* quality) { Q_UNUSED(quality); crashTest(control); } void android_camera_set_effect_mode(CameraControl* control, EffectMode mode) { Q_UNUSED(mode); crashTest(control); } void android_camera_get_effect_mode(CameraControl* control, EffectMode* mode) { Q_UNUSED(mode); crashTest(control); } void android_camera_get_preview_fps_range(CameraControl* control, int* min, int* max) { Q_UNUSED(min); Q_UNUSED(max); crashTest(control); } void android_camera_set_preview_fps(CameraControl* control, int fps) { Q_UNUSED(fps); crashTest(control); } void android_camera_get_preview_fps(CameraControl* control, int* fps) { Q_UNUSED(fps); crashTest(control); } void android_camera_enumerate_supported_preview_sizes(CameraControl* control, size_callback cb, void* ctx) { Q_UNUSED(cb); Q_UNUSED(ctx); crashTest(control); } void android_camera_enumerate_supported_picture_sizes(CameraControl* control, size_callback cb, void* ctx) { Q_UNUSED(cb); Q_UNUSED(ctx); crashTest(control); } void android_camera_get_preview_size(CameraControl* control, int* width, int* height) { Q_UNUSED(width); Q_UNUSED(height); crashTest(control); } void android_camera_set_preview_size(CameraControl* control, int width, int height) { Q_UNUSED(width); Q_UNUSED(height); crashTest(control); } void android_camera_get_picture_size(CameraControl* control, int* width, int* height) { Q_UNUSED(width); Q_UNUSED(height); crashTest(control); } void android_camera_set_picture_size(CameraControl* control, int width, int height) { Q_UNUSED(width); Q_UNUSED(height); crashTest(control); } void android_camera_get_current_zoom(CameraControl* control, int* zoom) { Q_UNUSED(zoom); crashTest(control); } void android_camera_get_max_zoom(CameraControl* control, int* zoom) { crashTest(control); *zoom = 4; } void android_camera_set_display_orientation(CameraControl* control, int32_t clockwise_rotation_degree) { Q_UNUSED(clockwise_rotation_degree); crashTest(control); } void android_camera_get_preview_texture_transformation(CameraControl* control, float m[16]) { Q_UNUSED(m); crashTest(control); } void android_camera_update_preview_texture(CameraControl* control) { crashTest(control); } void android_camera_set_preview_texture(CameraControl* control, int texture_id) { Q_UNUSED(texture_id); crashTest(control); } void android_camera_start_preview(CameraControl* control) { crashTest(control); } void android_camera_stop_preview(CameraControl* control) { crashTest(control); } void android_camera_start_autofocus(CameraControl* control) { crashTest(control); } void android_camera_stop_autofocus(CameraControl* control) { crashTest(control); } void android_camera_start_zoom(CameraControl* control, int32_t zoom) { Q_UNUSED(zoom); crashTest(control); } void android_camera_set_zoom(CameraControl* control, int32_t zoom) { Q_UNUSED(zoom); crashTest(control); } void android_camera_stop_zoom(CameraControl* control) { crashTest(control); } void android_camera_take_snapshot(CameraControl* control) { crashTest(control); } void android_camera_set_focus_region(CameraControl* control, FocusRegion* region) { Q_UNUSED(region); crashTest(control); } void android_camera_reset_focus_region(CameraControl* control) { crashTest(control); } void android_camera_set_rotation(CameraControl* control, int rotation) { Q_UNUSED(rotation); crashTest(control); } void android_camera_set_location(CameraControl* control, const float* latitude, const float* longitude, const float* altitude, int timestamp, const char* method) { Q_UNUSED(latitude); crashTest(control); } ./unittests/mocks/aal/camera_control.h0000644000015600001650000000157212675020550020160 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef CAMERA_CONTROL_H_ #define CAMERA_CONTROL_H_ #include #include #ifdef __cplusplus extern "C" { #endif struct CameraControlListener; struct CameraControl { CameraControlListener* listener; }; #ifdef __cplusplus } #endif #endif // CAMERA_CONTROL_H_ ./unittests/mocks/aal/camera_compatibility_layer.h0000644000015600001650000001356212675020550022547 0ustar jenkinsjenkins/* * Copyright (C) 2012 Canonical Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Authored by: Thomas Voss */ #ifndef CAMERA_COMPATIBILITY_LAYER_H_ #define CAMERA_COMPATIBILITY_LAYER_H_ //#include "camera_compatibility_layer_capabilities.h" #include #include #ifdef __cplusplus extern "C" { #endif // Forward declarations struct SfSurface; typedef enum { // This camera has higher quality and features like high resolution and flash BACK_FACING_CAMERA_TYPE, // The camera that is on the same side as the touch display. Usually used for video calls FRONT_FACING_CAMERA_TYPE } CameraType; struct CameraControl; struct CameraControlListener { typedef void (*on_msg_error)(void* context); typedef void (*on_msg_shutter)(void* context); typedef void (*on_msg_focus)(void* context); typedef void (*on_msg_zoom)(void* context, int32_t new_zoom_level); typedef void (*on_data_raw_image)(void* data, uint32_t data_size, void* context); typedef void (*on_data_compressed_image)(void* data, uint32_t data_size, void* context); typedef void (*on_preview_texture_needs_update)(void* context); // Called whenever an error occurs while the camera HAL executes a command on_msg_error on_msg_error_cb; // Called while taking a picture when the shutter has been triggered on_msg_shutter on_msg_shutter_cb; // Called while focusing on_msg_focus on_msg_focus_cb; // Called while zooming on_msg_zoom on_msg_zoom_cb; // Raw image data (Bayer pattern) is reported over this callback on_data_raw_image on_data_raw_image_cb; // JPEG-compressed image is reported over this callback on_data_compressed_image on_data_compressed_image_cb; // If a texture has been set as a destination for preview frames, // this callback is invoked whenever a new buffer from the camera is available // and needs to be uploaded to the texture by means of calling // android_camera_update_preview_texture. Please note that this callback can // be invoked on any thread, and android_camera_update_preview_texture must only // be called on the thread that setup the EGL/GL context. on_preview_texture_needs_update on_preview_texture_needs_update_cb; void* context; }; // Initializes a connection to the camera, returns NULL on error. CameraControl* android_camera_connect_to(CameraType camera_type, CameraControlListener* listener); // Disconnects the camera and deletes the pointer void android_camera_disconnect(CameraControl* control); int android_camera_lock(CameraControl* control); int android_camera_unlock(CameraControl* control); // Deletes the CameraControl void android_camera_delete(CameraControl* control); // Passes the rotation r of the display in [°] relative to the camera to the camera HAL. r \in [0, 359]. void android_camera_set_display_orientation(CameraControl* control, int32_t clockwise_rotation_degree); // Prepares the camera HAL to display preview images to the // supplied surface/texture in a H/W-acclerated way. New frames // are reported via the // 'on_preview_texture_needs_update'-callback, and clients of this // API should invoke android_camera_update_preview_texture // subsequently. Please note that the texture is bound automatically by the underlying // implementation. void android_camera_set_preview_texture(CameraControl* control, int texture_id); // Reads out the transformation matrix that needs to be applied when displaying the texture void android_camera_get_preview_texture_transformation(CameraControl* control, float m[16]); // Updates the texture to the last received frame and binds the texture void android_camera_update_preview_texture(CameraControl* control); // Prepares the camera HAL to display preview images to the supplied surface/texture in a H/W-acclerated way. void android_camera_set_preview_surface(CameraControl* control, SfSurface* surface); // Starts the camera preview void android_camera_start_preview(CameraControl* control); // Stops the camera preview void android_camera_stop_preview(CameraControl* control); // Starts an autofocus operation of the camera, results are reported via callback. void android_camera_start_autofocus(CameraControl* control); // Stops an ongoing autofocus operation. void android_camera_stop_autofocus(CameraControl* control); // Starts a zooming operation, zoom values are absolute, valid values [1, \infty]. void android_camera_start_zoom(CameraControl* control, int32_t zoom); // Stops an ongoing zoom operation. void android_camera_stop_zoom(CameraControl* control); // Adjust the zoom level immediately as opposed to smoothly zoomin gin. void android_camera_set_zoom(CameraControl* control, int32_t zoom); // Takes a picture and reports back image data via // callback. Please note that this stops the preview and thus, the // preview needs to be restarted after the picture operation has // completed. Ideally, this is done from the raw data callback. void android_camera_take_snapshot(CameraControl* control); #ifdef __cplusplus } #endif #endif // CAMERA_COMPATIBILITY_LAYER_H_ ./unittests/mocks/aal/media_recorder_layer.h0000644000015600001650000001141312675020550021323 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef RECORDER_COMPATIBILITY_LAYER_H_ #define RECORDER_COMPATIBILITY_LAYER_H_ #include #include #ifdef __cplusplus extern "C" { #endif struct MediaRecorderWrapper; struct CameraControl; // values are from andoid /frameworks/av/include/media/mediarecorder.h typedef enum { ANDROID_VIDEO_SOURCE_DEFAULT = 0, ANDROID_VIDEO_SOURCE_CAMERA = 1, ANDROID_VIDEO_SOURCE_GRALLOC_BUFFER = 2 } VideoSource; // values are from andoid /system/core/include/system/audio.h typedef enum { ANDROID_AUDIO_SOURCE_DEFAULT = 0, ANDROID_AUDIO_SOURCE_MIC = 1, ANDROID_AUDIO_SOURCE_VOICE_UPLINK = 2, ANDROID_AUDIO_SOURCE_VOICE_DOWNLINK = 3, ANDROID_AUDIO_SOURCE_VOICE_CALL = 4, ANDROID_AUDIO_SOURCE_CAMCORDER = 5, ANDROID_AUDIO_SOURCE_VOICE_RECOGNITION = 6, ANDROID_AUDIO_SOURCE_VOICE_COMMUNICATION = 7, ANDROID_AUDIO_SOURCE_REMOTE_SUBMIX = 8, ANDROID_AUDIO_SOURCE_CNT, ANDROID_AUDIO_SOURCE_MAX = ANDROID_AUDIO_SOURCE_CNT - 1 } AudioSource; // values are from andoid /frameworks/av/include/media/mediarecorder.h typedef enum { ANDROID_OUTPUT_FORMAT_DEFAULT = 0, ANDROID_OUTPUT_FORMAT_THREE_GPP = 1, ANDROID_OUTPUT_FORMAT_MPEG_4 = 2, ANDROID_OUTPUT_FORMAT_AUDIO_ONLY_START = 3, /* These are audio only file formats */ ANDROID_OUTPUT_FORMAT_RAW_AMR = 3, //to be backward compatible ANDROID_OUTPUT_FORMAT_AMR_NB = 3, ANDROID_OUTPUT_FORMAT_AMR_WB = 4, ANDROID_OUTPUT_FORMAT_AAC_ADIF = 5, ANDROID_OUTPUT_FORMAT_AAC_ADTS = 6, /* Stream over a socket, limited to a single stream */ ANDROID_OUTPUT_FORMAT_RTP_AVP = 7, /* H.264/AAC data encapsulated in MPEG2/TS */ ANDROID_OUTPUT_FORMAT_MPEG2TS = 8 } OutputFormat; // values are from andoid /frameworks/av/include/media/mediarecorder.h typedef enum { ANDROID_VIDEO_ENCODER_DEFAULT = 0, ANDROID_VIDEO_ENCODER_H263 = 1, ANDROID_VIDEO_ENCODER_H264 = 2, ANDROID_VIDEO_ENCODER_MPEG_4_SP = 3 } VideoEncoder; // values are from andoid /frameworks/av/include/media/mediarecorder.h typedef enum { ANDROID_AUDIO_ENCODER_DEFAULT = 0, ANDROID_AUDIO_ENCODER_AMR_NB = 1, ANDROID_AUDIO_ENCODER_AMR_WB = 2, ANDROID_AUDIO_ENCODER_AAC = 3, ANDROID_AUDIO_ENCODER_HE_AAC = 4, ANDROID_AUDIO_ENCODER_AAC_ELD = 5 } AudioEncoder; // Callback types typedef void (*on_recorder_msg_error)(void *context); // Callback setters void android_recorder_set_error_cb(MediaRecorderWrapper *mr, on_recorder_msg_error cb, void *context); // Main recorder control API MediaRecorderWrapper *android_media_new_recorder(); int android_recorder_initCheck(MediaRecorderWrapper *mr); int android_recorder_setCamera(MediaRecorderWrapper *mr, CameraControl* control); int android_recorder_setVideoSource(MediaRecorderWrapper *mr, VideoSource vs); int android_recorder_setAudioSource(MediaRecorderWrapper *mr, AudioSource as); int android_recorder_setOutputFormat(MediaRecorderWrapper *mr, OutputFormat of); int android_recorder_setVideoEncoder(MediaRecorderWrapper *mr, VideoEncoder ve); int android_recorder_setAudioEncoder(MediaRecorderWrapper *mr, AudioEncoder ae); int android_recorder_setOutputFile(MediaRecorderWrapper *mr, int fd); int android_recorder_setVideoSize(MediaRecorderWrapper *mr, int width, int height); int android_recorder_setVideoFrameRate(MediaRecorderWrapper *mr, int frames_per_second); int android_recorder_setParameters(MediaRecorderWrapper *mr, const char* parameters); int android_recorder_start(MediaRecorderWrapper *mr); int android_recorder_stop(MediaRecorderWrapper *mr); int android_recorder_prepare(MediaRecorderWrapper *mr); int android_recorder_reset(MediaRecorderWrapper *mr); int android_recorder_close(MediaRecorderWrapper *mr); int android_recorder_release(MediaRecorderWrapper *mr); #ifdef __cplusplus } #endif #endif ./unittests/aalcameracontrol/0000755000015600001650000000000012675020550016450 5ustar jenkinsjenkins./unittests/aalcameracontrol/aalcameraservice.cpp0000644000015600001650000000422412675020550022445 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameraservice.h" AalCameraService *AalCameraService::m_service = 0; class CameraControl {}; AalCameraService::AalCameraService(QObject *parent) : QMediaService(parent), m_androidControl(new CameraControl()), m_androidListener(0) { } AalCameraService::~AalCameraService() { delete m_androidControl; } QMediaControl *AalCameraService::requestControl(const char *name) { Q_UNUSED(name); return 0; } void AalCameraService::releaseControl(QMediaControl *control) { Q_UNUSED(control); } CameraControl *AalCameraService::androidControl() { return m_androidControl; } bool AalCameraService::connectCamera() { return true; } void AalCameraService::disconnectCamera() { } void AalCameraService::startPreview() { } void AalCameraService::stopPreview() { } bool AalCameraService::isPreviewStarted() const { return true; } bool AalCameraService::isCameraActive() const { return true; } void AalCameraService::enablePhotoMode() { } void AalCameraService::enableVideoMode() { } void AalCameraService::onApplicationStateChanged() { } void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener) { Q_UNUSED(camControl); Q_UNUSED(listener); } bool AalCameraService::isRecording() const { return false; } void AalCameraService::updateCaptureReady() { } QSize AalCameraService::selectSizeWithAspectRatio(const QList &sizes, float targetAspectRatio) const { Q_UNUSED(sizes); Q_UNUSED(targetAspectRatio); return QSize(); } ./unittests/aalcameracontrol/aalcameracontrol.pro0000644000015600001650000000066712675020550022512 0ustar jenkinsjenkinsinclude(../../coverage.pri) TARGET = tst_aalcameracontrol QT += testlib multimedia opengl LIBS += -L../mocks/aal -laal INCLUDEPATH += ../../src INCLUDEPATH += ../mocks/aal HEADERS += ../../src/aalcameracontrol.h \ ../../src/aalcameraservice.h SOURCES += tst_aalcameracontrol.cpp \ ../../src/aalcameracontrol.cpp \ aalcameraservice.cpp check.depends = $${TARGET} check.commands = ./$${TARGET} QMAKE_EXTRA_TARGETS += check ./unittests/aalcameracontrol/tst_aalcameracontrol.cpp0000644000015600001650000000365512675020550023366 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include "aalcameraservice.h" #define private public #include "aalcameracontrol.h" class tst_AalCameraControl : public QObject { Q_OBJECT private slots: void initTestCase(); void cleanupTestCase(); void setState(); void captureMode(); private: AalCameraControl *m_cameraControl; AalCameraService *m_service; }; void tst_AalCameraControl::initTestCase() { m_service = new AalCameraService(); m_cameraControl = new AalCameraControl(m_service); } void tst_AalCameraControl::cleanupTestCase() { delete m_cameraControl; delete m_service; } void tst_AalCameraControl::setState() { QSignalSpy spy(m_cameraControl, SIGNAL(stateChanged(QCamera::State))); QCamera::State state = QCamera::ActiveState; m_cameraControl->setState(state); QCOMPARE(m_cameraControl->state(), state); QCOMPARE(spy.count(), 1); } void tst_AalCameraControl::captureMode() { QSignalSpy spy(m_cameraControl, SIGNAL(captureModeChanged(QCamera::CaptureModes))); QCamera::CaptureModes mode = QCamera::CaptureVideo; m_cameraControl->setCaptureMode(mode); QCOMPARE(m_cameraControl->captureMode(), mode); QCOMPARE(spy.count(), 1); } QTEST_GUILESS_MAIN(tst_AalCameraControl) #include "tst_aalcameracontrol.moc" ./unittests/storagemanager/0000755000015600001650000000000012675020550016140 5ustar jenkinsjenkins./unittests/storagemanager/storagemanager.pro0000644000015600001650000000052312675020550021661 0ustar jenkinsjenkinsinclude(../../coverage.pri) TARGET = tst_storagemanager QT += testlib CONFIG += link_pkgconfig PKGCONFIG += exiv2 HEADERS += ../../src/storagemanager.h SOURCES += tst_storagemanager.cpp \ ../../src/storagemanager.cpp INCLUDEPATH += ../../src check.depends = $${TARGET} check.commands = ./$${TARGET} QMAKE_EXTRA_TARGETS += check ./unittests/storagemanager/tst_storagemanager.cpp0000644000015600001650000000737512675020550022551 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include #include #include #define private public #include "storagemanager.h" #include "data_validjpeg.h" #include "data_noexifjpeg.h" const QLatin1String testPath("/tmp/aalCameraStorageManagerUnitTestDirectory0192837465/"); class tst_StorageManager : public QObject { Q_OBJECT private slots: void initTestCase(); void cleanupTestCase(); void checkDirectory(); void fileNameGenerator_data(); void fileNameGenerator(); void updateEXIF(); private: void removeTestDirectory(); }; void tst_StorageManager::initTestCase() { removeTestDirectory(); } void tst_StorageManager::cleanupTestCase() { removeTestDirectory(); } void tst_StorageManager::checkDirectory() { StorageManager storage; QString path = testPath; bool ok = storage.checkDirectory(path); QCOMPARE(ok, true); QDir dir(path); ok = dir.exists(); QCOMPARE(ok, true); dir.rmdir(path); QString file = "image007.jpg"; ok = storage.checkDirectory(path+file); QCOMPARE(ok, true); dir.setPath(path); ok = dir.exists(); QCOMPARE(ok, true); dir.rmdir(path); } void tst_StorageManager::fileNameGenerator_data() { QTest::addColumn("extension"); QTest::newRow("jpg") << "jpg"; QTest::newRow("mp4") << "mp4"; } void tst_StorageManager::fileNameGenerator() { QFETCH(QString, extension); StorageManager storage; storage.m_directory = "/tmp"; const QLatin1String photoBase("image"); QString basePath = QString("/tmp/%1").arg(photoBase); QString date = QDate::currentDate().toString("yyyyMMdd"); QRegExp pattern(QString("%1\\d{8}_\\d{9}\\.%2").arg(basePath).arg(extension)); QString expectedPre = QString("%1%2").arg(basePath).arg(date); QString generated = storage.fileNameGenerator(photoBase, extension); QVERIFY(pattern.exactMatch(generated)); QStringList parts = generated.split('_'); QCOMPARE(parts.count(), 2); QString pre = parts[0]; QCOMPARE(pre, expectedPre); } void tst_StorageManager::removeTestDirectory() { QDir dir(testPath); QStringList fileNames = dir.entryList(QDir::Files); foreach (QString fileName, fileNames) { QFile::remove(testPath+fileName); } if (dir.exists()) dir.rmdir(testPath); } void tst_StorageManager::updateEXIF() { StorageManager storage; bool result; QTemporaryFile tmp; QVariantMap metadata; QByteArray invalidJPEG("INVALID_IMAGE"); result = storage.updateJpegMetadata(invalidJPEG, metadata, &tmp); QCOMPARE(result, false); result = storage.updateJpegMetadata(invalidJPEG, metadata, 0); QCOMPARE(result, false); result = storage.updateJpegMetadata(invalidJPEG, metadata, &tmp); QCOMPARE(result, false); result = storage.updateJpegMetadata(QByteArray((char*)data_validjpeg, data_validjpeg_len), metadata, &tmp); QCOMPARE(result, true); result = storage.updateJpegMetadata(QByteArray((char*)data_noexifjpeg, data_noexifjpeg_len), metadata, &tmp); QCOMPARE(result, true); } QTEST_GUILESS_MAIN(tst_StorageManager); #include "tst_storagemanager.moc" ./unittests/storagemanager/data_validjpeg.h0000644000015600001650000000772412675020550021261 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ unsigned char data_validjpeg[] = { 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x03, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x05, 0x08, 0x05, 0x05, 0x04, 0x04, 0x05, 0x0a, 0x07, 0x07, 0x06, 0x08, 0x0c, 0x0a, 0x0c, 0x0c, 0x0b, 0x0a, 0x0b, 0x0b, 0x0d, 0x0e, 0x12, 0x10, 0x0d, 0x0e, 0x11, 0x0e, 0x0b, 0x0b, 0x10, 0x16, 0x10, 0x11, 0x13, 0x14, 0x15, 0x15, 0x15, 0x0c, 0x0f, 0x17, 0x18, 0x16, 0x14, 0x18, 0x12, 0x14, 0x15, 0x14, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x09, 0x05, 0x05, 0x09, 0x14, 0x0d, 0x0b, 0x0d, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xff, 0xc2, 0x00, 0x11, 0x08, 0x00, 0x02, 0x00, 0x02, 0x03, 0x01, 0x11, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0xc4, 0x00, 0x14, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x10, 0x03, 0x10, 0x00, 0x00, 0x01, 0x54, 0x9f, 0xff, 0xc4, 0x00, 0x14, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x05, 0x02, 0x7f, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x03, 0x01, 0x01, 0x3f, 0x01, 0x7f, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x02, 0x01, 0x01, 0x3f, 0x01, 0x7f, 0xff, 0xc4, 0x00, 0x14, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x06, 0x3f, 0x02, 0x7f, 0xff, 0xc4, 0x00, 0x14, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x3f, 0x21, 0x7f, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x9f, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x03, 0x01, 0x01, 0x3f, 0x10, 0x7f, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x02, 0x01, 0x01, 0x3f, 0x10, 0x7f, 0xff, 0xc4, 0x00, 0x14, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x3f, 0x10, 0x7f, 0xff, 0xd9 }; unsigned int data_validjpeg_len = 539; ./unittests/storagemanager/data_noexifjpeg.h0000644000015600001650000000752612675020550021452 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ unsigned char data_noexifjpeg[] = { 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x03, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x05, 0x08, 0x05, 0x05, 0x04, 0x04, 0x05, 0x0a, 0x07, 0x07, 0x06, 0x08, 0x0c, 0x0a, 0x0c, 0x0c, 0x0b, 0x0a, 0x0b, 0x0b, 0x0d, 0x0e, 0x12, 0x10, 0x0d, 0x0e, 0x11, 0x0e, 0x0b, 0x0b, 0x10, 0x16, 0x10, 0x11, 0x13, 0x14, 0x15, 0x15, 0x15, 0x0c, 0x0f, 0x17, 0x18, 0x16, 0x14, 0x18, 0x12, 0x14, 0x15, 0x14, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x09, 0x05, 0x05, 0x09, 0x14, 0x0d, 0x0b, 0x0d, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0xff, 0xc2, 0x00, 0x11, 0x08, 0x00, 0x02, 0x00, 0x02, 0x03, 0x01, 0x11, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, 0x14, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xff, 0xc4, 0x00, 0x14, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x10, 0x03, 0x10, 0x00, 0x00, 0x01, 0x54, 0x9f, 0xff, 0xc4, 0x00, 0x14, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x05, 0x02, 0x7f, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x03, 0x01, 0x01, 0x3f, 0x01, 0x7f, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x02, 0x01, 0x01, 0x3f, 0x01, 0x7f, 0xff, 0xc4, 0x00, 0x14, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x06, 0x3f, 0x02, 0x7f, 0xff, 0xc4, 0x00, 0x14, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x3f, 0x21, 0x7f, 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x10, 0x9f, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x03, 0x01, 0x01, 0x3f, 0x10, 0x7f, 0xff, 0xc4, 0x00, 0x14, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x02, 0x01, 0x01, 0x3f, 0x10, 0x7f, 0xff, 0xc4, 0x00, 0x14, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x01, 0x3f, 0x10, 0x7f, 0xff, 0xd9 }; unsigned int data_noexifjpeg_len = 518; ./unittests/aalcameraexposurecontrol/0000755000015600001650000000000012675020550020243 5ustar jenkinsjenkins./unittests/aalcameraexposurecontrol/aalcameraservice.cpp0000644000015600001650000000451012675020550024236 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameraservice.h" #include "aalcameraexposurecontrol.h" #include "camera_control.h" #include "camera_compatibility_layer.h" AalCameraService *AalCameraService::m_service = 0; AalCameraService::AalCameraService(QObject *parent) : QMediaService(parent), m_androidControl(0), m_androidListener(0) { m_exposureControl = new AalCameraExposureControl(this); } AalCameraService::~AalCameraService() { delete m_exposureControl; } QMediaControl *AalCameraService::requestControl(const char *name) { Q_UNUSED(name); return 0; } void AalCameraService::releaseControl(QMediaControl *control) { Q_UNUSED(control); } CameraControl *AalCameraService::androidControl() { return m_androidControl; } bool AalCameraService::connectCamera() { m_androidListener = new CameraControlListener; m_androidControl = android_camera_connect_to(BACK_FACING_CAMERA_TYPE, m_androidListener); initControls(m_androidControl, m_androidListener); return true; } void AalCameraService::disconnectCamera() { delete m_androidListener; android_camera_disconnect(m_androidControl); } void AalCameraService::startPreview() { } void AalCameraService::stopPreview() { } bool AalCameraService::isPreviewStarted() const { return true; } void AalCameraService::onApplicationStateChanged() { } void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener) { m_exposureControl->init(camControl, listener); } void AalCameraService::updateCaptureReady() { } QSize AalCameraService::selectSizeWithAspectRatio(const QList &sizes, float targetAspectRatio) const { Q_UNUSED(sizes); Q_UNUSED(targetAspectRatio); return QSize(); } ./unittests/aalcameraexposurecontrol/aalcameraexposurecontrol.pro0000644000015600001650000000072712675020550026075 0ustar jenkinsjenkinsinclude(../../coverage.pri) TARGET = tst_aalcameraexposurecontrol QT += testlib multimedia opengl LIBS += -L../mocks/aal -laal INCLUDEPATH += ../../src INCLUDEPATH += ../mocks/aal HEADERS += ../../src/aalcameraexposurecontrol.h \ ../../src/aalcameraservice.h SOURCES += tst_aalcameraexposurecontrol.cpp \ ../../src/aalcameraexposurecontrol.cpp \ aalcameraservice.cpp check.depends = $${TARGET} check.commands = ./$${TARGET} QMAKE_EXTRA_TARGETS += check ./unittests/aalcameraexposurecontrol/tst_aalcameraexposurecontrol.cpp0000644000015600001650000000620112675020550026742 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include "aalcameraservice.h" #define private public #include "aalcameraexposurecontrol.h" class tst_AalCameraExposureControl : public QObject { Q_OBJECT private slots: void initTestCase(); void cleanupTestCase(); void setUnsupportedParameter(); void setExposureMode(); private: AalCameraExposureControl *m_exposureControl; AalCameraService *m_service; }; void tst_AalCameraExposureControl::initTestCase() { m_service = new AalCameraService(); m_exposureControl = m_service->exposureControl(); m_service->connectCamera(); } void tst_AalCameraExposureControl::cleanupTestCase() { delete m_service; } void tst_AalCameraExposureControl::setUnsupportedParameter() { QCameraExposureControl::ExposureParameter parameter = QCameraExposureControl::ISO; QSignalSpy spyActual(m_exposureControl, SIGNAL(actualValueChanged(int))); QSignalSpy spyRequested(m_exposureControl, SIGNAL(requestedValueChanged(int))); bool supported = m_exposureControl->isParameterSupported(parameter); bool valid = m_exposureControl->setValue(parameter, QVariant::fromValue(200)); QVariant requestedValue = m_exposureControl->requestedValue(parameter); QVariant actualValue = m_exposureControl->actualValue(parameter); QVERIFY(!supported); QVERIFY(!valid); QCOMPARE(requestedValue, QVariant()); QCOMPARE(actualValue, QVariant()); QCOMPARE(spyActual.count(), 0); QCOMPARE(spyRequested.count(), 0); } void tst_AalCameraExposureControl::setExposureMode() { QCameraExposureControl::ExposureParameter parameter = QCameraExposureControl::ExposureMode; QSignalSpy spyActual(m_exposureControl, SIGNAL(actualValueChanged(int))); QSignalSpy spyRequested(m_exposureControl, SIGNAL(requestedValueChanged(int))); bool supported = m_exposureControl->isParameterSupported(parameter); bool valid = m_exposureControl->setValue(parameter, QVariant::fromValue(QCameraExposure::ExposureSports)); QVariant requestedValue = m_exposureControl->requestedValue(parameter); QVariant actualValue = m_exposureControl->actualValue(parameter); QVERIFY(supported); QVERIFY(valid); QCOMPARE(requestedValue, QVariant::fromValue(QCameraExposure::ExposureSports)); QCOMPARE(actualValue, QVariant::fromValue(QCameraExposure::ExposureSports)); QCOMPARE(spyActual.count(), 1); QCOMPARE(spyRequested.count(), 1); } QTEST_GUILESS_MAIN(tst_AalCameraExposureControl) #include "tst_aalcameraexposurecontrol.moc" ./unittests/aalmediarecordercontrol/0000755000015600001650000000000012675020550020025 5ustar jenkinsjenkins./unittests/aalmediarecordercontrol/tst_aalmediarecordercontrol.cpp0000644000015600001650000000455612675020550026321 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include #include "aalcameraservice.h" #define private public #include "aalmediarecordercontrol.h" class tst_AalMediaRecorderControl : public QObject { Q_OBJECT private slots: void initTestCase(); void cleanupTestCase(); void setState(); private: AalMediaRecorderControl *m_recorderControl; AalCameraService *m_service; }; void tst_AalMediaRecorderControl::initTestCase() { m_service = new AalCameraService(); m_recorderControl = new AalMediaRecorderControl(m_service); m_service->connectCamera(); } void tst_AalMediaRecorderControl::cleanupTestCase() { delete m_recorderControl; delete m_service; } void tst_AalMediaRecorderControl::setState() { QString fileName("/tmp/videotest.avi"); QFile::remove(fileName); m_recorderControl->setOutputLocation(QUrl(fileName)); QCOMPARE(m_recorderControl->state(), QMediaRecorder::StoppedState); QCOMPARE(m_recorderControl->status(), QMediaRecorder::UnloadedStatus); m_recorderControl->setState(QMediaRecorder::RecordingState); QCOMPARE(m_recorderControl->state(), QMediaRecorder::RecordingState); QCOMPARE(m_recorderControl->status(), QMediaRecorder::RecordingStatus); m_recorderControl->setState(QMediaRecorder::PausedState); QCOMPARE(m_recorderControl->state(), QMediaRecorder::RecordingState); QCOMPARE(m_recorderControl->status(), QMediaRecorder::RecordingStatus); m_recorderControl->setState(QMediaRecorder::StoppedState); QCOMPARE(m_recorderControl->state(), QMediaRecorder::StoppedState); QCOMPARE(m_recorderControl->status(), QMediaRecorder::UnloadedStatus); } QTEST_GUILESS_MAIN(tst_AalMediaRecorderControl) #include "tst_aalmediarecordercontrol.moc" ./unittests/aalmediarecordercontrol/aalmediarecordercontrol.pro0000644000015600001650000000146112675020550025435 0ustar jenkinsjenkinsinclude(../../coverage.pri) TARGET = tst_aalmediarecordercontrol QT += testlib multimedia opengl LIBS += -L../mocks/aal -laal INCLUDEPATH += ../../src INCLUDEPATH += ../mocks/aal HEADERS += ../../src/aalmediarecordercontrol.h \ ../../src/aalcameraservice.h \ ../../src/aalvideoencodersettingscontrol.h \ ../../src/aalmetadatawritercontrol.h \ ../../src/audiocapture.h \ ../../src/storagemanager.h SOURCES += tst_aalmediarecordercontrol.cpp \ ../stubs/audiocapture_stub.cpp \ ../../src/aalmediarecordercontrol.cpp \ ../stubs/aalcameraservice_stub.cpp \ ../stubs/aalvideoencodersettingscontrol_stub.cpp \ ../stubs/aalmetadatawritercontrol_stub.cpp \ ../stubs/storagemanager_stub.cpp check.depends = $${TARGET} check.commands = ./$${TARGET} QMAKE_EXTRA_TARGETS += check ./unittests/aalcamerafocuscontrol/0000755000015600001650000000000012675020550017510 5ustar jenkinsjenkins./unittests/aalcamerafocuscontrol/storagemanager.cpp0000644000015600001650000000367312675020550023224 0ustar jenkinsjenkins/* * Copyright (C) 2016 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "storagemanager.h" StorageManager::StorageManager(QObject* parent) : QObject(parent) { } QString StorageManager::nextPhotoFileName(const QString &directoy) { Q_UNUSED(directoy); return QString(); } QString StorageManager::nextVideoFileName(const QString &directoy) { Q_UNUSED(directoy); return QString(); } bool StorageManager::checkDirectory(const QString &path) const { Q_UNUSED(path); return true; } QString StorageManager::fileNameGenerator(const QString &base, const QString& extension) { Q_UNUSED(base); Q_UNUSED(extension); return QString(); } bool StorageManager::updateJpegMetadata(QByteArray data, QVariantMap metadata, QTemporaryFile* destination) { Q_UNUSED(data); Q_UNUSED(metadata); Q_UNUSED(destination); return true; } SaveToDiskResult StorageManager::saveJpegImage(QByteArray data, QVariantMap metadata, QString fileName, QSize previewResolution, int captureID) { Q_UNUSED(data); Q_UNUSED(metadata); Q_UNUSED(fileName); Q_UNUSED(captureID); Q_UNUSED(previewResolution); return SaveToDiskResult(); } QString StorageManager::decimalToExifRational(double decimal) { Q_UNUSED(decimal); return QString(); } SaveToDiskResult::SaveToDiskResult() : success(false) { } ./unittests/aalcamerafocuscontrol/aalcamerafocuscontrol.pro0000644000015600001650000000111712675020550024601 0ustar jenkinsjenkinsinclude(../../coverage.pri) TARGET = tst_aalcamerafocuscontrol QT += testlib multimedia opengl LIBS += -L../mocks/aal -laal INCLUDEPATH += ../../src INCLUDEPATH += ../mocks/aal HEADERS += ../../src/aalcamerafocuscontrol.h \ ../../src/aalcameraservice.h \ ../../src/aalimagecapturecontrol.h \ ../../src/storagemanager.h SOURCES += tst_aalcamerafocuscontrol.cpp \ ../../src/aalcamerafocuscontrol.cpp \ storagemanager.cpp \ aalcameraservice.cpp \ aalimagecapturecontrol.cpp check.depends = $${TARGET} check.commands = ./$${TARGET} QMAKE_EXTRA_TARGETS += check ./unittests/aalcamerafocuscontrol/aalcameraservice.cpp0000644000015600001650000000355212675020550023510 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameraservice.h" AalCameraService *AalCameraService::m_service = 0; AalCameraService::AalCameraService(QObject *parent) : QMediaService(parent), m_androidControl(0), m_androidListener(0) { } AalCameraService::~AalCameraService() { } QMediaControl *AalCameraService::requestControl(const char *name) { Q_UNUSED(name); return 0; } void AalCameraService::releaseControl(QMediaControl *control) { Q_UNUSED(control); } CameraControl *AalCameraService::androidControl() { return m_androidControl; } bool AalCameraService::connectCamera() { return true; } void AalCameraService::disconnectCamera() { } void AalCameraService::startPreview() { } void AalCameraService::stopPreview() { } bool AalCameraService::isPreviewStarted() const { return true; } void AalCameraService::onApplicationStateChanged() { } void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener) { Q_UNUSED(camControl); Q_UNUSED(listener); } void AalCameraService::updateCaptureReady() { } QSize AalCameraService::selectSizeWithAspectRatio(const QList &sizes, float targetAspectRatio) const { Q_UNUSED(sizes); Q_UNUSED(targetAspectRatio); return QSize(); } ./unittests/aalcamerafocuscontrol/tst_aalcamerafocuscontrol.cpp0000644000015600001650000001113012675020550025451 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include "aalcameraservice.h" #define private public #include "aalcamerafocuscontrol.h" class tst_AalCameraFocusControl : public QObject { Q_OBJECT private slots: void init(); void cleanup(); void customPoint(); void focusMode(); void focusModeAfterDoubleInit(); void focusPointMode(); void point2Region_data(); void point2Region(); private: AalCameraFocusControl *m_focusControl; AalCameraService *m_service; }; void tst_AalCameraFocusControl::init() { m_service = new AalCameraService(); m_focusControl = new AalCameraFocusControl(m_service); } void tst_AalCameraFocusControl::cleanup() { delete m_focusControl; delete m_service; } void tst_AalCameraFocusControl::customPoint() { QSignalSpy spy(m_focusControl, SIGNAL(customFocusPointChanged(const QPointF &))); QPointF point(0.2, 0.3); m_focusControl->setCustomFocusPoint(point); QCOMPARE(m_focusControl->customFocusPoint(), point); QCOMPARE(spy.count(), 1); } void tst_AalCameraFocusControl::focusMode() { QSignalSpy spy(m_focusControl, SIGNAL(focusModeChanged(QCameraFocus::FocusModes))); QCameraFocus::FocusModes mode = QCameraFocus::InfinityFocus; m_focusControl->setFocusMode(mode); QCOMPARE(m_focusControl->focusMode(), mode); QCOMPARE(spy.count(), 1); } void tst_AalCameraFocusControl::focusModeAfterDoubleInit() { // default focusMode is AutoFocus QCOMPARE(m_focusControl->focusMode(), QCameraFocus::AutoFocus); // set focusMode to ContinuousFocus QSignalSpy spy(m_focusControl, SIGNAL(focusModeChanged(QCameraFocus::FocusModes))); QCameraFocus::FocusModes mode = QCameraFocus::InfinityFocus; m_focusControl->setFocusMode(mode); QCOMPARE(m_focusControl->focusMode(), mode); QCOMPARE(spy.count(), 1); // checking that focusMode does not change upon init() spy.clear(); CameraControlListener* androidListener = new CameraControlListener; CameraControl* androidControl = android_camera_connect_to(BACK_FACING_CAMERA_TYPE, androidListener); m_focusControl->init(androidControl, androidListener); QCOMPARE(m_focusControl->focusMode(), mode); QCOMPARE(spy.count(), 0); // checking that focusMode does not change upon second call to init() // This happens for example upon switching cameras or reactivating the camera spy.clear(); m_focusControl->init(androidControl, androidListener); QCOMPARE(m_focusControl->focusMode(), mode); QCOMPARE(spy.count(), 0); delete androidListener; } void tst_AalCameraFocusControl::focusPointMode() { QSignalSpy spy(m_focusControl, SIGNAL(focusPointModeChanged(QCameraFocus::FocusPointMode))); QCameraFocus::FocusPointMode mode = QCameraFocus::FocusPointCenter; m_focusControl->setFocusPointMode(mode); QCOMPARE(m_focusControl->focusPointMode(), mode); QCOMPARE(spy.count(), 1); } void tst_AalCameraFocusControl::point2Region_data() { QTest::addColumn("x"); QTest::addColumn("y"); QTest::addColumn("left"); QTest::addColumn("right"); QTest::addColumn("top"); QTest::addColumn("bottom"); QTest::newRow("center") << (qreal)0.5 << (qreal)0.5 << -100 << 100 << -100 << 100; QTest::newRow("topLeft") << (qreal)0.0 << (qreal)1.0 << -1000 << -800 << 800 << 1000; QTest::newRow("bottomRight") << (qreal)1.0 << (qreal)0.0 << 800 << 1000 << -1000 << -800; } void tst_AalCameraFocusControl::point2Region() { QFETCH(qreal, x); QFETCH(qreal, y); QFETCH(int, left); QFETCH(int, right); QFETCH(int, top); QFETCH(int, bottom); AalCameraFocusControl focusControl(0); QPointF point(x, y); FocusRegion region; region = m_focusControl->point2Region(point); QCOMPARE(region.left, left); QCOMPARE(region.right, right); QCOMPARE(region.top, top); QCOMPARE(region.bottom, bottom); } QTEST_GUILESS_MAIN(tst_AalCameraFocusControl) #include "tst_aalcamerafocuscontrol.moc" ./unittests/aalcamerafocuscontrol/aalimagecapturecontrol.cpp0000644000015600001650000000317412675020550024746 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalimagecapturecontrol.h" #include #include AalImageCaptureControl::AalImageCaptureControl(AalCameraService *service, QObject *parent) : QCameraImageCaptureControl(parent) { Q_UNUSED(service); } AalImageCaptureControl::~AalImageCaptureControl() { } int AalImageCaptureControl::capture(const QString &fileName) { Q_UNUSED(fileName); return 0; } void AalImageCaptureControl::cancelCapture() { } bool AalImageCaptureControl::isReadyForCapture() const { return true; } void AalImageCaptureControl::init(CameraControl *control, CameraControlListener *listener) { Q_UNUSED(control); Q_UNUSED(listener); } void AalImageCaptureControl::setReady(bool ready) { Q_UNUSED(ready); } void AalImageCaptureControl::shutter() { } void AalImageCaptureControl::onImageFileSaved() { } void AalImageCaptureControl::saveJpeg(const QByteArray& data) { Q_UNUSED(data); } ./unittests/stubs/0000755000015600001650000000000012675020550014301 5ustar jenkinsjenkins./unittests/stubs/qcamerainfodata.h0000644000015600001650000000216612675020550017576 0ustar jenkinsjenkins/* * Copyright (C) 2016 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef QCAMERAINFODATA_H #define QCAMERAINFODATA_H #include class CameraInfo { public: CameraInfo(QString deviceID = QString(), QString description = QString(), int orientation = 0, QCamera::Position position = QCamera::UnspecifiedPosition); QString deviceID; QString description; int orientation; QCamera::Position position; }; class QCameraInfoData { public: static QList availableDevices; }; #endif // QCAMERAINFODATA_H ./unittests/stubs/qcamerainfo_stub.cpp0000644000015600001650000000537512675020550020341 0ustar jenkinsjenkins/* * Copyright (C) 2016 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include "qcamerainfodata.h" class QCameraInfoPrivate { public: QString deviceID; QString description; int orientation; QCamera::Position position; }; QCameraInfo::QCameraInfo(const QByteArray &name) : d(new QCameraInfoPrivate()) { QStringList info = QString::fromLatin1(name).split('|'); d->deviceID = info.at(0); d->description = info.at(1); d->orientation = info.at(2).toInt(); d->position = QCamera::Position(info.at(3).toInt()); } QCameraInfo::QCameraInfo(const QCamera &camera) : d(new QCameraInfoPrivate()) { Q_UNUSED(camera); } QCameraInfo::QCameraInfo(const QCameraInfo& other) : d(new QCameraInfoPrivate()) { d->deviceID = other.deviceName(); d->description = other.description(); d->orientation = other.orientation(); d->position = other.position(); } QCameraInfo::~QCameraInfo() { } QCameraInfo& QCameraInfo::operator=(const QCameraInfo& other) { if (this != &other) { d->deviceID = other.deviceName(); d->description = other.description(); d->orientation = other.orientation(); d->position = other.position(); } return *this; } bool QCameraInfo::operator==(const QCameraInfo &other) const { Q_UNUSED(other); return false; } bool QCameraInfo::isNull() const { return false; } QString QCameraInfo::deviceName() const { return d->deviceID; } QString QCameraInfo::description() const { return d->description; } QCamera::Position QCameraInfo::position() const { return d->position; } int QCameraInfo::orientation() const { return d->orientation; } QCameraInfo QCameraInfo::defaultCamera() { return QCameraInfo(); } QList QCameraInfo::availableCameras(QCamera::Position position) { Q_UNUSED(position); QList list; Q_FOREACH(CameraInfo info, QCameraInfoData::availableDevices) { QString infoString = QString("%1|%2|%3|%4").arg(info.deviceID).arg(info.description) .arg(info.orientation).arg(info.position); QCameraInfo camera(infoString.toLatin1()); list.append(camera); } return list; } ./unittests/stubs/storagemanager_stub.cpp0000644000015600001650000000247412675020550021050 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include "storagemanager.h" StorageManager::StorageManager(QObject* parent) { Q_UNUSED(parent); } QString StorageManager::nextPhotoFileName(const QString &directory) { Q_UNUSED(directory); return QString(); } QString StorageManager::nextVideoFileName(const QString &directory) { Q_UNUSED(directory); return QString(); } bool StorageManager::checkDirectory(const QString &path) const { Q_UNUSED(path); return true; } QString StorageManager::fileNameGenerator(const QString &base, const QString& extension) { Q_UNUSED(base); Q_UNUSED(extension); return QString(); } ./unittests/stubs/aalmetadatawritercontrol_stub.cpp0000644000015600001650000000310512675020550023135 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalmetadatawritercontrol.h" #include "aalcameraservice.h" AalMetaDataWriterControl::AalMetaDataWriterControl(AalCameraService *service, QObject *parent) : QMetaDataWriterControl(parent), m_service(service) { } QStringList AalMetaDataWriterControl::availableMetaData() const { QStringList keys; return keys; } bool AalMetaDataWriterControl::isMetaDataAvailable() const { return true; } bool AalMetaDataWriterControl::isWritable() const { return true; } QVariant AalMetaDataWriterControl::metaData(const QString &key) const { Q_UNUSED(key); return QVariant(); } void AalMetaDataWriterControl::setMetaData(const QString &key, const QVariant &value) { m_metaData[key] = value; } int AalMetaDataWriterControl::orientation() const { return m_orientation; } int AalMetaDataWriterControl::correctedOrientation() const { return m_orientation; } void AalMetaDataWriterControl::clearAllMetaData() { } ./unittests/stubs/audiocapture_stub.cpp0000644000015600001650000000223412675020550020530 0ustar jenkinsjenkins/* * Copyright (C) 2014 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "audiocapture.h" #include #include AudioCapture::AudioCapture(MediaRecorderWrapper *mediaRecorder) { Q_UNUSED(mediaRecorder); } AudioCapture::~AudioCapture() { } bool AudioCapture::init(RecorderReadAudioCallback cb, void *context) { Q_UNUSED(cb); Q_UNUSED(context); return true; } void AudioCapture::stopCapture() { } int AudioCapture::setupMicrophoneStream() { } void AudioCapture::run() { } int AudioCapture::readMicrophone() { return 0; } ./unittests/stubs/aalvideoencodersettingscontrol_stub.cpp0000644000015600001650000000412712675020550024354 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalvideoencodersettingscontrol.h" #include "aalcameraservice.h" const QSize AalVideoEncoderSettingsControl::DEFAULT_SIZE = QSize(1280,720); const int AalVideoEncoderSettingsControl::DEFAULT_FPS = 30; AalVideoEncoderSettingsControl::AalVideoEncoderSettingsControl(AalCameraService *service, QObject *parent) : QVideoEncoderSettingsControl(parent), m_service(service) { } void AalVideoEncoderSettingsControl::setVideoSettings(const QVideoEncoderSettings &settings) { Q_UNUSED(settings); } QList AalVideoEncoderSettingsControl::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const { Q_UNUSED(settings); Q_UNUSED(continuous); QList fps; fps << 30; return fps; } QList AalVideoEncoderSettingsControl::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const { Q_UNUSED(settings); Q_UNUSED(continuous); return m_availableSizes; } QStringList AalVideoEncoderSettingsControl::supportedVideoCodecs() const { QStringList codecs; codecs << QString("H.264"); return codecs; } QString AalVideoEncoderSettingsControl::videoCodecDescription(const QString &codec) const { return codec; } QVideoEncoderSettings AalVideoEncoderSettingsControl::videoSettings() const { return m_settings; } float AalVideoEncoderSettingsControl::getAspectRatio() const { return 16.0 / 9.0; } void AalVideoEncoderSettingsControl::resetAllSettings() { } ./unittests/stubs/aalmediarecordercontrol_stub.cpp0000644000015600001650000000472212675020550022733 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameraservice.h" #include "aalmediarecordercontrol.h" AalMediaRecorderControl::AalMediaRecorderControl(AalCameraService *service, QObject *parent) : QMediaRecorderControl(parent), m_service(service), m_mediaRecorder(0), m_duration(0), m_currentState(QMediaRecorder::StoppedState), m_currentStatus(QMediaRecorder::UnloadedStatus), m_recordingTimer(0) { } AalMediaRecorderControl::~AalMediaRecorderControl() { } void AalMediaRecorderControl::applySettings() { qDebug() << Q_FUNC_INFO << " is not used"; } qint64 AalMediaRecorderControl::duration() const { return m_duration; } bool AalMediaRecorderControl::isMuted() const { return false; } QUrl AalMediaRecorderControl::outputLocation() const { return m_outputLocation; } bool AalMediaRecorderControl::setOutputLocation(const QUrl &location) { Q_UNUSED(location); return true; } QMediaRecorder::State AalMediaRecorderControl::state() const { return m_currentState; } QMediaRecorder::Status AalMediaRecorderControl::status() const { return m_currentStatus; } qreal AalMediaRecorderControl::volume() const { return 1.0; } void AalMediaRecorderControl::init() { } void AalMediaRecorderControl::deleteRecorder() { } void AalMediaRecorderControl::setMuted(bool muted) { Q_UNUSED(muted); } void AalMediaRecorderControl::setState(QMediaRecorder::State state) { Q_UNUSED(state); } void AalMediaRecorderControl::setVolume(qreal gain) { Q_UNUSED(gain); } void AalMediaRecorderControl::updateDuration() { } void AalMediaRecorderControl::handleError() { Q_EMIT error(-1, "Error on recording video"); } void AalMediaRecorderControl::setStatus(QMediaRecorder::Status status) { Q_UNUSED(status); } int AalMediaRecorderControl::startRecording() { return 0; } void AalMediaRecorderControl::stopRecording() { } ./unittests/stubs/aalcameracontrol_stub.cpp0000644000015600001650000000410712675020550021353 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameracontrol.h" #include "aalcameraservice.h" #include AalCameraControl::AalCameraControl(AalCameraService *service, QObject *parent) : QCameraControl(parent), m_service(service), m_state(QCamera::UnloadedState), m_status(QCamera::UnloadedStatus), m_captureMode(QCamera::CaptureStillImage) { } AalCameraControl::~AalCameraControl() { } QCamera::State AalCameraControl::state() const { return m_state; } void AalCameraControl::setState(QCamera::State state) { m_state = state; Q_EMIT stateChanged(m_state); } QCamera::Status AalCameraControl::status() const { return m_status; } QCamera::CaptureModes AalCameraControl::captureMode() const { return m_captureMode; } void AalCameraControl::setCaptureMode(QCamera::CaptureModes mode) { m_captureMode = mode; Q_EMIT captureModeChanged(mode); } bool AalCameraControl::isCaptureModeSupported(QCamera::CaptureModes mode) const { Q_UNUSED(mode); return true; } bool AalCameraControl::canChangeProperty(QCameraControl::PropertyChangeType changeType, QCamera::Status status) const { Q_UNUSED(changeType); Q_UNUSED(status); return true; } void AalCameraControl::init(CameraControl *control, CameraControlListener *listener) { Q_UNUSED(control); Q_UNUSED(listener); } void AalCameraControl::handleError() { } void AalCameraControl::errorCB(void *context) { Q_UNUSED(context); } ./unittests/stubs/qcamerainfodata.cpp0000644000015600001650000000175312675020550020132 0ustar jenkinsjenkins/* * Copyright (C) 2016 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "qcamerainfodata.h" QList QCameraInfoData::availableDevices = QList(); CameraInfo::CameraInfo(QString deviceID, QString description, int orientation, QCamera::Position position) : deviceID(deviceID), description(description), orientation(orientation), position(position) { } ./unittests/stubs/aalcameraservice_stub.cpp0000644000015600001650000000436412675020550021340 0ustar jenkinsjenkins/* * Copyright (C) 2013 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "aalcameraservice.h" #include "aalvideoencodersettingscontrol.h" #include "storagemanager.h" #include "camera_control.h" AalCameraService *AalCameraService::m_service = 0; AalCameraService::AalCameraService(QObject *parent) : QMediaService(parent), m_metadataWriter(0), m_androidControl(0), m_androidListener(0) { m_storageManager = new StorageManager; m_videoEncoderControl = new AalVideoEncoderSettingsControl(this); } AalCameraService::~AalCameraService() { delete m_storageManager; delete m_androidControl; delete m_videoEncoderControl; } QMediaControl *AalCameraService::requestControl(const char *name) { Q_UNUSED(name); return 0; } void AalCameraService::releaseControl(QMediaControl *control) { Q_UNUSED(control); } CameraControl *AalCameraService::androidControl() { return m_androidControl; } bool AalCameraService::connectCamera() { m_androidControl = new CameraControl; return true; } void AalCameraService::disconnectCamera() { } void AalCameraService::startPreview() { } void AalCameraService::stopPreview() { } void AalCameraService::onApplicationStateChanged() { } void AalCameraService::initControls(CameraControl *camControl, CameraControlListener *listener) { delete m_androidControl; m_androidControl = 0; Q_UNUSED(camControl); Q_UNUSED(listener); } bool AalCameraService::isCameraActive() const { return true; } bool AalCameraService::isBackCameraUsed() const { return true; } void AalCameraService::updateCaptureReady() { } StorageManager *AalCameraService::storageManager() { return m_storageManager; } ./coverage.pri0000644000015600001650000000356112675020550013413 0ustar jenkinsjenkins# Coverage CONFIG(coverage) { OBJECTS_DIR = MOC_DIR = TOP_SRC_DIR = $$PWD LIBS += -lgcov QMAKE_CXXFLAGS += --coverage QMAKE_LDFLAGS += --coverage QMAKE_EXTRA_TARGETS += coverage cov QMAKE_EXTRA_TARGETS += clean-gcno clean-gcda coverage-html \ generate-coverage-html clean-coverage-html coverage-gcovr \ generate-gcovr generate-coverage-gcovr clean-coverage-gcovr clean-gcno.commands = \ "@echo Removing old coverage instrumentation"; \ "find -name '*.gcno' -print | xargs -r rm" clean-gcda.commands = \ "@echo Removing old coverage results"; \ "find -name '*.gcda' -print | xargs -r rm" coverage-html.depends = clean-gcda check generate-coverage-html generate-coverage-html.commands = \ "@echo Collecting coverage data"; \ "lcov --directory $${TOP_SRC_DIR} --capture --output-file coverage.info --no-checksum --compat-libtool"; \ "lcov --extract coverage.info \"*/src/*.cpp\" -o coverage.info"; \ "lcov --remove coverage.info \"moc_*.cpp\" -o coverage.info"; \ "LANG=C genhtml --prefix $${TOP_SRC_DIR} --output-directory coverage-html --title \"Code Coverage\" --legend --show-details coverage.info" clean-coverage-html.depends = clean-gcda clean-coverage-html.commands = \ "lcov --directory $${TOP_SRC_DIR} -z"; \ "rm -rf coverage.info coverage-html" coverage-gcovr.depends = clean-gcda check generate-coverage-gcovr generate-coverage-gcovr.commands = \ "@echo Generating coverage GCOVR report"; \ "gcovr -x -r $${TOP_SRC_DIR} -o $${TOP_SRC_DIR}/coverage.xml -e \".*/moc_.*\" -e \"unittests/.*\" -e \".*\\.h\"" clean-coverage-gcovr.depends = clean-gcda clean-coverage-gcovr.commands = \ "rm -rf $${TOP_SRC_DIR}/coverage.xml" QMAKE_CLEAN += *.gcda *.gcno coverage.info coverage.xml } ./aalCamera.pro0000644000015600001650000000015312675020550013466 0ustar jenkinsjenkinsinclude(coverage.pri) TEMPLATE = subdirs SUBDIRS += \ src \ unittests OTHER_FILES += .qmake.conf ./.qmake.conf0000644000015600001650000000017412675020550013124 0ustar jenkinsjenkinsPKG_CONFIG_ARCH = $$section(QMAKE_CC, -, 0, -2) !isEmpty (PKG_CONFIG_ARCH) { PKG_CONFIG = $$PKG_CONFIG_ARCH-pkg-config }