--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/camerauis/cameraxui/cxengine/src/cxestillcapturecontroldesktop.cpp Wed Aug 18 09:37:18 2010 +0300
@@ -0,0 +1,594 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+#include <QPixmap>
+
+#include "cxestillcapturecontroldesktop.h"
+#include "cxeimagedataitemdesktop.h"
+#include "cxeimagedataqueuedesktop.h"
+#include "cxefilenamegenerator.h"
+#include "cxefilesavethreaddesktop.h"
+#include "cxutils.h"
+#include "cxecameradevicecontrol.h"
+#include "cxestillimagedesktop.h"
+#include "cxeviewfindercontrol.h"
+#include "cxeviewfindercontroldesktop.h"
+#include "cxeautofocuscontrol.h"
+#include "cxestate.h"
+#include "cxecameradevicedesktop.h"
+
+// constants
+const int KMaintainAspectRatio = false;
+
+
+
+/**
+ * Constructor.
+ */
+CxeStillCaptureControlDesktop::CxeStillCaptureControlDesktop(
+ CxeCameraDeviceDesktop &cameraDevice,
+ CxeViewfinderControl &viewfinderControl,
+ CxeCameraDeviceControl &cameraDeviceControl,
+ CxeFilenameGenerator &nameGenerator,
+ CxeAutoFocusControl &autoFocusControl,
+ CxeFileSaveThread &saveThread) :
+ mCameraDevice(cameraDevice),
+ mState(CxeStillCaptureControl::Uninitialized),
+ mViewfinderControl(viewfinderControl),
+ mCameraDeviceControl(cameraDeviceControl),
+ mFilenameGenerator(nameGenerator),
+ mAutoFocusControl(autoFocusControl),
+ mMode(SingleImageCapture),
+ mAfState(CxeAutoFocusControl::Unknown),
+ mSaveThread(saveThread)
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ qRegisterMetaType<CxeStillCaptureControl::State>();
+ initializeStates();
+ reset();
+
+ mImageDataQueue = new CxeImageDataQueueDesktop();
+
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+/**
+ * Destructor.
+ */
+CxeStillCaptureControlDesktop::~CxeStillCaptureControlDesktop()
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ deinit();
+ reset();
+ mSupportedImageQualities.clear();
+ delete mImageDataQueue;
+
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+/**
+ * Return the current state.
+ */
+CxeStillCaptureControl::State CxeStillCaptureControlDesktop::state() const
+{
+ return mState;
+}
+
+/**
+ * Initialize the control states.
+ */
+void CxeStillCaptureControlDesktop::initializeStates()
+{
+
+ // addState( id, name, allowed next states )
+}
+
+/**
+ * Initialize the still image capture control.
+ */
+void CxeStillCaptureControlDesktop::init()
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ if (state() == Uninitialized) {
+ CxeImageDetails dummyDetails;
+ dummyDetails.mAspectRatio = Cxe::AspectRatio4to3;
+ dummyDetails.mEstimatedSize = 10000;
+ dummyDetails.mHeight = 360;
+ dummyDetails.mWidth = 640;
+ mSupportedImageQualities.append(dummyDetails);
+ prepare();
+ }
+
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+/**
+ * Un-initialize the image mode.
+ */
+void CxeStillCaptureControlDesktop::deinit()
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ if (state() == Uninitialized) {
+ // nothing to do
+ CX_DEBUG_EXIT_FUNCTION();
+ return;
+ }
+ mState = Uninitialized;
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+
+/*!
+ * Prepare still capture mode.
+ */
+void CxeStillCaptureControlDesktop::prepare()
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ if (state() != Uninitialized) {
+ // wrong state and we return
+ return;
+ }
+
+ int err = 0;
+ CxeError::Id cxErr = getImageQualityDetails(mCurrentImageDetails);
+ int ecamStillResolutionIndex = 0;
+
+ if (cxErr == CxeError::None) {
+ int imageWidth = mCurrentImageDetails.mWidth;
+ int imageHeight = mCurrentImageDetails.mHeight;
+ CX_DEBUG(("CxeStillCaptureControlSymbian::prepare <> resolution = (%d, %d)", imageWidth, imageHeight));
+
+ if (ecamStillResolutionIndex < 0) {
+ CX_DEBUG(("CxeStillCaptureControlSymbian::prepare - WARNING! resolution not supported, falling back to index 0"));
+ ecamStillResolutionIndex = 0;
+ }
+
+ CX_DEBUG(("PrepareImageCaptureL done, err=%d, resolution index = %d", err, ecamStillResolutionIndex));
+
+ if (!err) {
+ // still capture prepare went fine, try preparing snapshot
+ err = prepareStillSnapshot();
+ }
+ } else {
+ err = 0;
+ }
+
+ if (!err) {
+ // If viewfinder is already running, this call does nothing
+ mViewfinderControl.start();
+ // inform zoom control to prepare zoom
+ emit prepareZoomForStill(ecamStillResolutionIndex);
+ } else {
+ CX_DEBUG(("Image Prepare FAILED! symbian error = %d", err));
+ }
+ mState = Ready;
+ emit imagePrepareComplete(CxeError::None);
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+
+
+/*!
+ Prepare still snapshot
+ Returns symbian error code.
+ */
+int CxeStillCaptureControlDesktop::prepareStillSnapshot()
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ handleSnapshotEvent(CxeError::None);
+
+ CX_DEBUG_EXIT_FUNCTION();
+
+ return 0;
+}
+
+
+/*!
+ imageInfo contains image qualities details
+ Returns CxeError error code.
+ */
+CxeError::Id CxeStillCaptureControlDesktop::getImageQualityDetails(CxeImageDetails &imageInfo)
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ int imageQuality = 0;
+ CxeError::Id err = CxeError::None;
+ if (mCameraDeviceControl.cameraIndex() == Cxe::PrimaryCameraIndex) {
+ bool validQuality = (imageQuality >= 0 && imageQuality < mSupportedImageQualities.count());
+
+ if (err == CxeError::None && validQuality ) {
+ // get image quality details
+ imageInfo = mSupportedImageQualities.at(imageQuality);
+ } else {
+ err = CxeError::NotFound;
+ CX_DEBUG(("Invalid ImageQuality = %d", imageQuality));
+ }
+ } else {
+ // we are in secondary camera
+ // get secondary camera image quality details
+ imageInfo = mSupportedImageQualities.at(imageQuality);
+ }
+
+ CX_DEBUG_EXIT_FUNCTION();
+ return err;
+}
+
+
+/**
+ * Command to start image capture now.
+ */
+void CxeStillCaptureControlDesktop::capture()
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ //! @todo: NOTE: This call may not stay here. It can move depending on the implementation for burst capture.
+ if (mMode == BurstCapture) {
+ // Start a new filename sequence
+ mFilenameGenerator.startNewImageFilenameSequence();
+ }
+ emit imageCaptured(CxeError::None, 0);
+ handleSnapshotEvent(CxeError::None);
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+
+/**
+ * Snapshot ready notification. Ask the snapshot from snapshot interface.
+ * NB: Typically snapshot arrives before image data but can be in reverse
+ * order as well.
+ */
+void CxeStillCaptureControlDesktop::handleSnapshotEvent(CxeError::Id error)
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ if (state() == CxeStillCaptureControl::Uninitialized) {
+ // we ignore this event, when we are not active
+ return;
+ }
+
+ if (error) {
+ emit snapshotReady(error, QImage(), 0);
+ }
+
+ // Get image container for current snapshot index.
+ // Remember to increment counter.
+ CxeStillImageDesktop* stillImage = getImageForIndex(mNextSnapshotIndex++);
+
+ // When the snapshot ready event is handled, prepare new filename.
+ if (stillImage->filename().isEmpty()) {
+ // Error ignored at this point, try again when image data arrives.
+ prepareFilename(stillImage);
+ }
+
+ CxeImageDataItem* dataItem = new CxeImageDataItemDesktop(mNextImageDataIndex++, stillImage->snapshot(), stillImage->filename(), stillImage->id());
+
+ stillImage->setDataItem(dataItem);
+
+ mSaveThread.save(dataItem);
+
+ emit snapshotReady(CxeError::None, QImage(), stillImage->id());
+ emit imageCaptured(CxeError::None, stillImage->id());
+
+ mState = Ready;
+ emit stateChanged(mState, CxeError::None);
+
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+
+
+/**
+ * Settings changed, needs updated
+ */
+void CxeStillCaptureControlDesktop::handleSettingValueChanged(const QString& settingId,QVariant newValue)
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ if (settingId == CxeSettingIds::FLASH_MODE) {
+ updateFlashSetting(newValue);
+ } else if (settingId == CxeSettingIds::LIGHT_SENSITIVITY) {
+ updateISOSetting(newValue);
+ } else if (settingId == CxeSettingIds::EV_COMPENSATION_VALUE) {
+ updateEVCompensationSetting(newValue);
+ } else if (settingId == CxeSettingIds::IMAGE_QUALITY) {
+ // re-prepare for still
+ deinit();
+ init();
+ } else {
+ // do nothing
+ }
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+/**
+ * Image Scene mode changed, needs updated
+ */
+void CxeStillCaptureControlDesktop::handleSceneChanged(CxeScene& scene)
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ if (mCameraDeviceControl.cameraIndex() == Cxe::PrimaryCameraIndex){
+ CX_DEBUG_ASSERT(scene.count() != 0);
+ // we are interested only in the following settings in this class scope
+
+ if(scene.contains(CxeSettingIds::FLASH_MODE)) {
+ CX_DEBUG(("CxeStillCaptureControlSymbian::handleSceneChanged scene->mFlashMode = %d", scene[CxeSettingIds::FLASH_MODE].toInt()));
+ updateFlashSetting(scene[CxeSettingIds::FLASH_MODE]);
+ }
+
+ if(scene.contains(CxeSettingIds::LIGHT_SENSITIVITY)) {
+ updateISOSetting(scene[CxeSettingIds::LIGHT_SENSITIVITY]);
+ }
+
+ if(scene.contains(CxeSettingIds::EV_COMPENSATION_VALUE)) {
+ updateEVCompensationSetting(scene[CxeSettingIds::EV_COMPENSATION_VALUE]);
+ }
+ }
+
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+/**
+ * UpdateFlashSetting
+ */
+void CxeStillCaptureControlDesktop::updateFlashSetting(QVariant newValue)
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ Q_UNUSED(newValue);
+
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+/**
+ * UpdateISOSetting
+ */
+void CxeStillCaptureControlDesktop::updateISOSetting(QVariant newValue)
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ Q_UNUSED(newValue);
+
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+/**
+ * UpdateEVCompensationSetting
+ */
+void CxeStillCaptureControlDesktop::updateEVCompensationSetting(QVariant newValue)
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ Q_UNUSED(newValue);
+
+
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+
+/**
+ * ECam reference changing, release resources
+ */
+void CxeStillCaptureControlDesktop::prepareForCameraDelete()
+{
+ CX_DEBUG_ENTER_FUNCTION();
+ deinit();
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+/**
+ * Camera being released. Cancel ongoing capture, if any.
+ */
+void CxeStillCaptureControlDesktop::prepareForRelease()
+{
+ CX_DEBUG_ENTER_FUNCTION();
+ deinit();
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+/**
+ * New camera available,
+ */
+void CxeStillCaptureControlDesktop::handleCameraAllocated(CxeError::Id error)
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ if (error == CxeError::None) {
+ // load all still resoultions supported by ecam
+ // load all still qualities supported by icm
+ mSupportedImageQualities.clear();
+ // get list of supported image qualities based on camera index
+
+ }
+
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+/**
+ * Return number of images captured (during current capture operation only).
+ */
+int CxeStillCaptureControlDesktop::imageCount() const
+{
+ return mImages.count();
+}
+
+/**
+ * Reset the image array.
+ */
+void CxeStillCaptureControlDesktop::reset()
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ qDeleteAll(mImages);
+ mImages.clear();
+
+ mNextSnapshotIndex = 0;
+ mNextImageDataIndex = 0;
+
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+/**
+ * This should cancel any ongoing image captures.
+ */
+void CxeStillCaptureControlDesktop::cancelAll()
+{
+ mImageDataQueue->clear();
+ reset();
+}
+
+/**
+ * Sets the current capture mode: SingleImageCapture / BurstCapture.
+ */
+void CxeStillCaptureControlDesktop::setMode(CaptureMode mode)
+{
+ mMode = mode;
+}
+
+/**
+ * Returns the current capture mode.
+ */
+CxeStillCaptureControl::CaptureMode CxeStillCaptureControlDesktop::mode() const
+{
+ return mMode;
+}
+
+/**
+ * Operator [] - returns the indexed image from capture array.
+ */
+CxeStillImage &CxeStillCaptureControlDesktop::operator[](int index)
+{
+ return *mImages[ index ];
+}
+
+/**
+ * Getter for image data queue.
+ */
+CxeImageDataQueue &CxeStillCaptureControlDesktop::imageDataQueue()
+{
+ return *mImageDataQueue;
+}
+
+/**
+ * Generates a filename and sets it in the still image object.
+ * Skips the process if filename already copied exists in the object. This
+ * behaviour is required in rare cases where image data arrives before snapshot.
+ */
+CxeError::Id CxeStillCaptureControlDesktop::prepareFilename(CxeStillImageDesktop *stillImage)
+{
+ CxeError::Id err = CxeError::None;
+ if (stillImage->filename().isEmpty()) {
+ QString path;
+
+ QString fileExt = mCurrentImageDetails.mImageFileExtension;
+
+ if (mMode == SingleImageCapture) {
+ err = mFilenameGenerator.generateFilename(path, fileExt);
+ }
+ else {
+ err = mFilenameGenerator.nextImageFilenameInSequence(path, fileExt);
+ }
+
+ if (!err) {
+ CX_DEBUG(( "Next image file path: %s", path.toAscii().constData() ));
+ stillImage->setFilename(path);
+ }
+ else {
+ //! @todo: Error ID can be returned by this function.
+ // Also error can be detected from empty filename string.
+ CX_DEBUG(("ERROR in filename generation. err:%d", err));
+ }
+ }
+ return err;
+}
+
+/*!
+* Helper method to set orientation data from the orientation sensor
+*/
+void CxeStillCaptureControlDesktop::setOrientation(QVariant sensorData)
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ Q_UNUSED(sensorData);
+
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+/**
+ * Get the image container at given index or create a new one if needed.
+ */
+CxeStillImageDesktop* CxeStillCaptureControlDesktop::getImageForIndex(int index)
+{
+ CxeStillImageDesktop* image(NULL);
+
+ if (mImages.count() <= index) {
+ image = new CxeStillImageDesktop();
+ image->setSnapshot(mCameraDevice.currentSnaphot());
+ mImages.append(image);
+ } else {
+ CX_DEBUG_ASSERT( mNextImageDataIndex >= 0 && index < mImages.count() );
+ image = mImages[index];
+ }
+ return image;
+}
+
+
+/*!
+* Slot to handle Autofocus events.
+*/
+void CxeStillCaptureControlDesktop::handleAutofocusStateChanged(
+ CxeAutoFocusControl::State newState,
+ CxeError::Id /*error*/ )
+{
+ CX_DEBUG_ENTER_FUNCTION();
+
+ mAfState = newState;
+ CxeAutoFocusControl::Mode mode = mAutoFocusControl.mode();
+
+ // if focused and in correct mode, play sound
+ if (newState == CxeAutoFocusControl::Ready &&
+ mode != CxeAutoFocusControl::Hyperfocal &&
+ mode != CxeAutoFocusControl::Infinity) {
+ }
+ CX_DEBUG_EXIT_FUNCTION();
+}
+
+
+/*!
+* Returns supported image qualities based on the camera index
+* (primary/secondary).
+*/
+QList<CxeImageDetails> CxeStillCaptureControlDesktop::supportedImageQualities()
+{
+ return QList<CxeImageDetails>();
+}
+
+/*!
+* Returns the number of images left for the current image quality setting
+*/
+int CxeStillCaptureControlDesktop::imagesLeft()
+{
+ return 100; // Stub: Dummy value
+}
+
+// end of file