camerauis/cameraxui/cxengine/src/cxestillcapturecontrolsymbian.cpp
changeset 43 0e652f8f1fbd
parent 28 3075d9b614e6
child 45 24fd82631616
equal deleted inserted replaced
28:3075d9b614e6 43:0e652f8f1fbd
     1 /*
     1 /*
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     2 * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     4 * This component and the accompanying materials are made available
     5 * under the terms of "Eclipse Public License v1.0"
     5 * under the terms of "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
    16 */
    16 */
    17 
    17 
    18 
    18 
    19 #include <algorithm>
    19 #include <algorithm>
    20 #include <exception>
    20 #include <exception>
    21 #include <fbs.h>
       
    22 #include <QPixmap>
    21 #include <QPixmap>
    23 #include <coemain.h>
    22 #include <coemain.h>
    24 #include <ECamOrientationCustomInterface2.h>
    23 #include <ECamOrientationCustomInterface2.h>
    25 #include <ecam/camerasnapshot.h>
       
    26 #include <ecamfacetrackingcustomapi.h>
    24 #include <ecamfacetrackingcustomapi.h>
    27 
    25 
    28 #include "cxestillcapturecontrolsymbian.h"
    26 #include "cxestillcapturecontrolsymbian.h"
    29 #include "cxeimagedataqueuesymbian.h"
    27 #include "cxeimagedataqueuesymbian.h"
    30 #include "cxefilenamegenerator.h"
    28 #include "cxefilenamegenerator.h"
    32 #include "cxutils.h"
    30 #include "cxutils.h"
    33 #include "cxecameradevicecontrol.h"
    31 #include "cxecameradevicecontrol.h"
    34 #include "cxecameradevice.h"
    32 #include "cxecameradevice.h"
    35 #include "cxesoundplayersymbian.h"
    33 #include "cxesoundplayersymbian.h"
    36 #include "cxestillimagesymbian.h"
    34 #include "cxestillimagesymbian.h"
    37 #include "cxeviewfindercontrol.h"
       
    38 #include "cxeviewfindercontrolsymbian.h"
    35 #include "cxeviewfindercontrolsymbian.h"
       
    36 #include "cxesnapshotcontrol.h"
    39 #include "cxesettingsmappersymbian.h"
    37 #include "cxesettingsmappersymbian.h"
    40 #include "cxestate.h"
    38 #include "cxestate.h"
    41 #include "cxesettings.h"
    39 #include "cxesettings.h"
    42 #include "cxeerrormappingsymbian.h"
    40 #include "cxeerrormappingsymbian.h"
    43 #include "cxeautofocuscontrol.h"
    41 #include "cxeautofocuscontrol.h"
    51 #include "cxestillcapturecontrolsymbianTraces.h"
    49 #include "cxestillcapturecontrolsymbianTraces.h"
    52 #endif
    50 #endif
    53 
    51 
    54 
    52 
    55 // constants
    53 // constants
    56 const int KMaintainAspectRatio = false;
    54 namespace
    57 const TInt64 KMinRequiredSpaceImage = 2000000;
    55 {
    58 
    56     const TInt64 KMinRequiredSpaceImage = 2000000;
    59 
    57 }
    60 /**
    58 
       
    59 /*!
    61  * Constructor.
    60  * Constructor.
    62  */
    61  */
    63 CxeStillCaptureControlSymbian::CxeStillCaptureControlSymbian(
    62 CxeStillCaptureControlSymbian::CxeStillCaptureControlSymbian(
    64     CxeCameraDevice &cameraDevice,
    63     CxeCameraDevice &cameraDevice,
    65     CxeViewfinderControl &viewfinderControl,
    64     CxeViewfinderControl &viewfinderControl,
       
    65     CxeSnapshotControl &snapshotControl,
    66     CxeCameraDeviceControl &cameraDeviceControl,
    66     CxeCameraDeviceControl &cameraDeviceControl,
    67     CxeFilenameGenerator &nameGenerator,
    67     CxeFilenameGenerator &nameGenerator,
    68     CxeSensorEventHandler &sensorEventHandler,
    68     CxeSensorEventHandler &sensorEventHandler,
    69     CxeAutoFocusControl &autoFocusControl,
    69     CxeAutoFocusControl &autoFocusControl,
    70     CxeSettings &settings,
    70     CxeSettings &settings,
    72     CxeFileSaveThread &fileSaveThread,
    72     CxeFileSaveThread &fileSaveThread,
    73     CxeDiskMonitor &diskMonitor)
    73     CxeDiskMonitor &diskMonitor)
    74     : CxeStateMachine("CxeStillCaptureControlSymbian"),
    74     : CxeStateMachine("CxeStillCaptureControlSymbian"),
    75       mCameraDevice(cameraDevice),
    75       mCameraDevice(cameraDevice),
    76       mViewfinderControl(viewfinderControl),
    76       mViewfinderControl(viewfinderControl),
       
    77       mSnapshotControl(snapshotControl),
    77       mCameraDeviceControl(cameraDeviceControl),
    78       mCameraDeviceControl(cameraDeviceControl),
    78       mFilenameGenerator(nameGenerator),
    79       mFilenameGenerator(nameGenerator),
    79       mSensorEventHandler(sensorEventHandler),
    80       mSensorEventHandler(sensorEventHandler),
    80       mAutoFocusControl(autoFocusControl),
    81       mAutoFocusControl(autoFocusControl),
    81       mSettings(settings),
    82       mSettings(settings),
   114             this, SLOT(handleSettingValueChanged(const QString&,QVariant)));
   115             this, SLOT(handleSettingValueChanged(const QString&,QVariant)));
   115 
   116 
   116     // Connect ECam image buffer ready event
   117     // Connect ECam image buffer ready event
   117     connect(&mCameraDeviceControl, SIGNAL(imageBufferReady(MCameraBuffer*,int)),
   118     connect(&mCameraDeviceControl, SIGNAL(imageBufferReady(MCameraBuffer*,int)),
   118             this, SLOT(handleImageData(MCameraBuffer*,int)));
   119             this, SLOT(handleImageData(MCameraBuffer*,int)));
   119     // Connect signals for ECam events
   120     // connect snapshot ready signal
   120     connect(&mCameraDeviceControl, SIGNAL(cameraEvent(int,int)),
   121     connect(&mSnapshotControl, SIGNAL(snapshotReady(CxeError::Id, const QImage&)),
   121             this, SLOT(handleCameraEvent(int,int)));
   122             this, SLOT(handleSnapshotReady(CxeError::Id, const QImage&)));
   122 
   123 
   123     OstTrace0(camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_CREATE_MID2, "msg: e_CX_ENGINE_CONNECT_SIGNALS 0");
   124     OstTrace0(camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_CREATE_MID2, "msg: e_CX_ENGINE_CONNECT_SIGNALS 0");
   124 
   125 
   125     mImageDataQueue = new CxeImageDataQueueSymbian();
   126     mImageDataQueue = new CxeImageDataQueueSymbian();
   126     mAutoFocusSoundPlayer = new CxeSoundPlayerSymbian(CxeSoundPlayerSymbian::AutoFocus);
   127     mAutoFocusSoundPlayer = new CxeSoundPlayerSymbian(CxeSoundPlayerSymbian::AutoFocus, mSettings);
   127     mCaptureSoundPlayer = new CxeSoundPlayerSymbian(CxeSoundPlayerSymbian::StillCapture);
   128     mCaptureSoundPlayer = new CxeSoundPlayerSymbian(CxeSoundPlayerSymbian::StillCapture, mSettings);
   128 
   129 
   129     OstTrace0(camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_CREATE_OUT, "msg: e_CX_STILLCAPTURECONTROL_NEW 0");
   130     OstTrace0(camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_CREATE_OUT, "msg: e_CX_STILLCAPTURECONTROL_NEW 0");
   130     CX_DEBUG_EXIT_FUNCTION();
   131     CX_DEBUG_EXIT_FUNCTION();
   131 }
   132 }
   132 
   133 
   133 /**
   134 /*!
   134  * Destructor.
   135  * Destructor.
   135  */
   136  */
   136 CxeStillCaptureControlSymbian::~CxeStillCaptureControlSymbian()
   137 CxeStillCaptureControlSymbian::~CxeStillCaptureControlSymbian()
   137 {
   138 {
   138     CX_DEBUG_ENTER_FUNCTION();
   139     CX_DEBUG_ENTER_FUNCTION();
   146     delete mAutoFocusSoundPlayer;
   147     delete mAutoFocusSoundPlayer;
   147 
   148 
   148     CX_DEBUG_EXIT_FUNCTION();
   149     CX_DEBUG_EXIT_FUNCTION();
   149 }
   150 }
   150 
   151 
   151 /**
   152 /*!
   152  * Return the current state.
   153  * Return the current state.
   153  */
   154  */
   154 CxeStillCaptureControl::State CxeStillCaptureControlSymbian::state() const
   155 CxeStillCaptureControl::State CxeStillCaptureControlSymbian::state() const
   155 {
   156 {
   156     return static_cast<CxeStillCaptureControl::State>( stateId() );
   157     return static_cast<CxeStillCaptureControl::State>( stateId() );
   157 }
   158 }
   158 
   159 
   159 /**
   160 /*!
   160  * Handle state changed event. Normally just emits the signal
   161  * Handle state changed event. Normally just emits the signal
   161  * for observers to react appropriately.
   162  * for observers to react appropriately.
   162  */
   163  */
   163 void CxeStillCaptureControlSymbian::handleStateChanged( int newStateId, CxeError::Id error )
   164 void CxeStillCaptureControlSymbian::handleStateChanged( int newStateId, CxeError::Id error )
   164 {
   165 {
   165     emit stateChanged( static_cast<State>( newStateId ), error );
   166     emit stateChanged( static_cast<State>( newStateId ), error );
   166 }
   167 }
   167 
   168 
   168 /**
   169 /*!
   169  * Initialize the control states.
   170  * Initialize the control states.
   170  */
   171  */
   171 void CxeStillCaptureControlSymbian::initializeStates()
   172 void CxeStillCaptureControlSymbian::initializeStates()
   172 {
   173 {
   173     // addState( id, name, allowed next states )
   174     // addState( id, name, allowed next states )
   176     addState(new CxeState( Capturing , "Capturing", Uninitialized | Ready));
   177     addState(new CxeState( Capturing , "Capturing", Uninitialized | Ready));
   177 
   178 
   178     setInitialState(Uninitialized);
   179     setInitialState(Uninitialized);
   179 }
   180 }
   180 
   181 
   181 /**
   182 /*!
   182  * Initialize the still image capture control.
   183  * Initialize the still image capture control.
   183  */
   184  */
   184 void CxeStillCaptureControlSymbian::init()
   185 void CxeStillCaptureControlSymbian::init()
   185 {
   186 {
   186     CX_DEBUG_ENTER_FUNCTION();
   187     CX_DEBUG_ENTER_FUNCTION();
   194 
   195 
   195     OstTrace0(camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_INIT_OUT, "msg: e_CX_STILL_CAPCONT_INIT 0");
   196     OstTrace0(camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_INIT_OUT, "msg: e_CX_STILL_CAPCONT_INIT 0");
   196     CX_DEBUG_EXIT_FUNCTION();
   197     CX_DEBUG_EXIT_FUNCTION();
   197 }
   198 }
   198 
   199 
   199 /**
   200 /*!
   200  * Un-initialize the image mode.
   201  * Un-initialize the image mode.
   201  */
   202  */
   202 void CxeStillCaptureControlSymbian::deinit()
   203 void CxeStillCaptureControlSymbian::deinit()
   203 {
   204 {
   204     CX_DEBUG_ENTER_FUNCTION();
   205     CX_DEBUG_ENTER_FUNCTION();
   206     if (state() == Uninitialized) {
   207     if (state() == Uninitialized) {
   207         // nothing to do
   208         // nothing to do
   208         return;
   209         return;
   209     }
   210     }
   210 
   211 
   211     OstTrace0( camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_DEINIT_IN, "msg: e_CX_STILL_CAPCONT_DEINIT 1" );
   212     OstTrace0( camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_DEINIT_IN, "msg: e_CX_STILLCAPCONT_DEINIT 1" );
   212 
   213 
   213     // Stop monitoring disk space.
   214     // Stop monitoring disk space.
   214     mDiskMonitor.stop();
   215     mDiskMonitor.stop();
   215     disconnect(&mDiskMonitor, SIGNAL(diskSpaceChanged()), this, SLOT(handleDiskSpaceChanged()));
   216     disconnect(&mDiskMonitor, SIGNAL(diskSpaceChanged()), this, SLOT(handleDiskSpaceChanged()));
   216 
   217 
   217     //stop viewfinder
   218     //stop viewfinder
   218     mViewfinderControl.stop();
   219     mViewfinderControl.stop();
   219 
   220 
       
   221     if (state() == Capturing) {
       
   222         mCameraDevice.camera()->CancelCaptureImage();
       
   223     }
       
   224 
   220     // disable sensor event handler.
   225     // disable sensor event handler.
   221     mSensorEventHandler.deinit();
   226     mSensorEventHandler.deinit();
   222 
   227 
   223     if (mCameraDevice.cameraSnapshot()) {
   228     mSnapshotControl.stop();
   224         mCameraDevice.cameraSnapshot()->StopSnapshot();
   229 
   225     }
       
   226 
       
   227     if (state() == Capturing) {
       
   228         mCameraDevice.camera()->CancelCaptureImage();
       
   229     }
       
   230     setState(Uninitialized);
   230     setState(Uninitialized);
   231 
   231 
   232     OstTrace0( camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_DEINIT_OUT, "msg: e_CX_STILL_CAPCONT_DEINIT 0" );
   232     OstTrace0( camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_DEINIT_OUT, "msg: e_CX_STILLCAPCONT_DEINIT 0" );
   233     CX_DEBUG_EXIT_FUNCTION();
   233     CX_DEBUG_EXIT_FUNCTION();
   234 }
   234 }
   235 
   235 
   236 
   236 
   237 /**!
   237 /*!
   238  * Prepare still capture mode.
   238  * Prepare still capture mode.
   239  */
   239  */
   240 void CxeStillCaptureControlSymbian::prepare()
   240 void CxeStillCaptureControlSymbian::prepare()
   241 {
   241 {
   242     CX_DEBUG_ENTER_FUNCTION();
   242     CX_DEBUG_ENTER_FUNCTION();
   244     if (state() != Uninitialized) {
   244     if (state() != Uninitialized) {
   245         // wrong state and we return
   245         // wrong state and we return
   246         return;
   246         return;
   247     }
   247     }
   248 
   248 
   249     OstTrace0( camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_PREPARE_IN, "msg: e_CX_STILLCAPCONT_PREPARE 1" );
   249     OstTrace0(camerax_performance, CXESTILLCAPTURECONTROL_PREPARE_IN, "msg: e_CX_STILLCAPCONT_PREPARE 1");
   250 
   250 
   251     int err = KErrNone;
   251     int err = KErrNone;
   252     CxeError::Id cxErr = getImageQualityDetails(mCurrentImageDetails);
   252     CxeError::Id cxErr = getImageQualityDetails(mCurrentImageDetails);
   253     int ecamStillResolutionIndex = 0;
   253     int ecamStillResolutionIndex = 0;
   254 
   254 
   269             ecamStillResolutionIndex = 0;
   269             ecamStillResolutionIndex = 0;
   270         }
   270         }
   271 
   271 
   272         // Prepare Image capture
   272         // Prepare Image capture
   273         CCamera::TFormat imgFormat = supportedStillFormat(mCameraDeviceControl.cameraIndex());
   273         CCamera::TFormat imgFormat = supportedStillFormat(mCameraDeviceControl.cameraIndex());
   274         OstTrace0(camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_PREPARE_MID1, "msg: e_CX_PREPARE_IMAGE_CAPTURE 1");
   274         OstTrace0(camerax_performance, CXESTILLCAPTURECONTROL_PREPARE_MID1, "msg: e_CX_PREPARE_IMAGE_CAPTURE 1");
   275         TRAP(err, mCameraDevice.camera()->PrepareImageCaptureL(imgFormat, ecamStillResolutionIndex));
   275         TRAP(err, mCameraDevice.camera()->PrepareImageCaptureL(imgFormat, ecamStillResolutionIndex));
   276         OstTrace0(camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_PREPARE_MID2, "msg: e_CX_PREPARE_IMAGE_CAPTURE 0");
   276         OstTrace0(camerax_performance, CXESTILLCAPTURECONTROL_PREPARE_MID2, "msg: e_CX_PREPARE_IMAGE_CAPTURE 0");
   277 
   277 
   278         CX_DEBUG(("PrepareImageCaptureL done, err=%d, resolution index = %d", err, ecamStillResolutionIndex));
   278         CX_DEBUG(("PrepareImageCaptureL done, err=%d, resolution index = %d", err, ecamStillResolutionIndex));
   279 
   279 
   280         if (!err) {
   280         if (!err) {
   281             // still capture prepare went fine, try preparing snapshot
   281             // still capture prepare went fine, try preparing snapshot
   316     }
   316     }
   317 
   317 
   318     // Inform interested parties that image mode has been prepared for capture
   318     // Inform interested parties that image mode has been prepared for capture
   319     emit imagePrepareComplete(CxeErrorHandlingSymbian::map(err));
   319     emit imagePrepareComplete(CxeErrorHandlingSymbian::map(err));
   320 
   320 
   321     OstTrace0( camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_PREPARE_OUT, "msg: e_CX_STILLCAPCONT_PREPARE 0" );
   321     OstTrace0(camerax_performance, CXESTILLCAPTURECONTROL_GOTOSTILL, "msg: e_CX_GO_TO_STILL_MODE 0");
   322 
   322     OstTrace0(camerax_performance, CXESTILLCAPTURECONTROL_PREPARE_OUT, "msg: e_CX_STILLCAPCONT_PREPARE 0");
   323     CX_DEBUG_EXIT_FUNCTION();
   323 
   324 }
   324     CX_DEBUG_EXIT_FUNCTION();
   325 
   325 }
   326 
   326 
   327 
   327 
   328 /**!
   328 
       
   329 /*!
   329  Prepare still snapshot
   330  Prepare still snapshot
   330  Returns symbian error code.
   331  Returns symbian error code.
   331  */
   332  */
   332 int CxeStillCaptureControlSymbian::prepareStillSnapshot()
   333 int CxeStillCaptureControlSymbian::prepareStillSnapshot()
   333 {
   334 {
   334     CX_DEBUG_ENTER_FUNCTION();
   335     CX_DEBUG_ENTER_FUNCTION();
   335 
   336     OstTrace0( camerax_performance, CXESTILLCAPTURECONTROL_PREPARESNAP_1, "msg: e_CX_PREPARE_SNAPSHOT 1" );
   336     CCamera::CCameraSnapshot *cameraSnapshot = mCameraDevice.cameraSnapshot();
   337 
   337     CX_ASSERT_ALWAYS(cameraSnapshot);
   338     int status(KErrNone);
   338 
   339     try {
   339     int err = KErrNone;
   340         QSize snapshotSize = mSnapshotControl.calculateSnapshotSize(
   340     // Whether or not we have postcapture on, we need the snapshot for Thumbnail Manager.
   341                                 mViewfinderControl.deviceDisplayResolution(),
   341     if (cameraSnapshot) {
   342                                 mCurrentImageDetails.mAspectRatio);
   342         // Cancel active snapshot
   343         mSnapshotControl.start(snapshotSize);
   343         cameraSnapshot->StopSnapshot();
   344     } catch (...) {
   344 
   345         status = KErrGeneral;
   345         // Prepare snapshot
   346     }
   346         CCamera::TFormat snapFormat = CCamera::EFormatFbsBitmapColor16MU;
   347     OstTrace0( camerax_performance, CXESTILLCAPTURECONTROL_PREPARESNAP_2, "msg: e_CX_PREPARE_SNAPSHOT 0" );
   347         OstTrace0( camerax_performance, DUP4_CXESTILLCAPTURECONTROLSYMBIAN_PREPARE, "msg: e_CX_PREPARE_SNAPSHOT 1" );
   348 
   348         TRAP(err, cameraSnapshot->PrepareSnapshotL(snapFormat,
   349     CX_DEBUG_EXIT_FUNCTION();
   349                                                    getSnapshotSize(),
   350     return status;
   350                                                    KMaintainAspectRatio));
   351 }
   351         OstTrace0( camerax_performance, DUP5_CXESTILLCAPTURECONTROLSYMBIAN_PREPARE, "msg: e_CX_PREPARE_SNAPSHOT 0" );
   352 
   352         CX_DEBUG(("PrepareSnapshotL done, err=%d", err));
   353 
   353 
   354 /*!
   354         // Start snapshot if no errors encountered.
       
   355         if (err == KErrNone) {
       
   356             CX_DEBUG(("Start still snapshot"));
       
   357             cameraSnapshot->StartSnapshot();
       
   358         }
       
   359     } else {
       
   360         // No snapshot interface available. Report error.
       
   361         // Assert above takes care of this, but keeping this as an option.
       
   362         err = KErrNotReady;
       
   363     }
       
   364 
       
   365     CX_DEBUG_EXIT_FUNCTION();
       
   366 
       
   367     return err;
       
   368 }
       
   369 
       
   370 
       
   371 /**!
       
   372  imageInfo contains image qualities details
   355  imageInfo contains image qualities details
   373  Returns CxeError error code.
   356  Returns CxeError error code.
   374  */
   357  */
   375 CxeError::Id CxeStillCaptureControlSymbian::getImageQualityDetails(CxeImageDetails &imageInfo)
   358 CxeError::Id CxeStillCaptureControlSymbian::getImageQualityDetails(CxeImageDetails &imageInfo)
   376 {
   359 {
   377     CX_DEBUG_ENTER_FUNCTION();
   360     CX_DEBUG_ENTER_FUNCTION();
       
   361     OstTrace0( camerax_performance, CXESTILLCAPTURECONTROL_GETQUALITYDETAILS_1, "msg: e_CX_GET_QUALITY_DETAILS 1" );
   378 
   362 
   379     int imageQuality = 0;
   363     int imageQuality = 0;
   380     CxeError::Id err = CxeError::None;
   364     CxeError::Id err = CxeError::None;
   381     if (mCameraDeviceControl.cameraIndex() == Cxe::PrimaryCameraIndex) {
   365     if (mCameraDeviceControl.cameraIndex() == Cxe::PrimaryCameraIndex) {
   382         err = mSettings.get(CxeSettingIds::IMAGE_QUALITY, imageQuality);
   366         err = mSettings.get(CxeSettingIds::IMAGE_QUALITY, imageQuality);
   394         // we are in secondary camera
   378         // we are in secondary camera
   395         // get secondary camera image quality details
   379         // get secondary camera image quality details
   396        imageInfo = mIcmSupportedImageResolutions.at(imageQuality);
   380        imageInfo = mIcmSupportedImageResolutions.at(imageQuality);
   397     }
   381     }
   398 
   382 
       
   383     OstTrace0( camerax_performance, CXESTILLCAPTURECONTROL_GETQUALITYDETAILS_2, "msg: e_CX_GET_QUALITY_DETAILS 0" );
   399     CX_DEBUG_EXIT_FUNCTION();
   384     CX_DEBUG_EXIT_FUNCTION();
   400     return err;
   385     return err;
   401 }
   386 }
   402 
   387 
   403 
   388 /*!
   404 /*!
       
   405 * Returns snapshot size. Snapshot size is calculated based on the
       
   406 * display resolution and current image aspect ratio.
       
   407 */
       
   408 TSize CxeStillCaptureControlSymbian::getSnapshotSize() const
       
   409 {
       
   410     CX_DEBUG_ENTER_FUNCTION();
       
   411 
       
   412     TSize snapshotSize;
       
   413 
       
   414     QSize deviceResolution = mViewfinderControl.deviceDisplayResolution();
       
   415     QSize size = QSize(mCurrentImageDetails.mWidth, mCurrentImageDetails.mHeight);
       
   416 
       
   417     // scale according to aspect ratio.
       
   418     size.scale(deviceResolution.width(), deviceResolution.height(), Qt::KeepAspectRatio);
       
   419     CX_DEBUG(("Still Snapshot size, (%d,%d)", size.width(), size.height()));
       
   420     snapshotSize.SetSize(size.width(), deviceResolution.height());
       
   421 
       
   422     CX_DEBUG_EXIT_FUNCTION();
       
   423 
       
   424     return snapshotSize;
       
   425 }
       
   426 
       
   427 
       
   428 /**
       
   429  * Command to start image capture now.
   389  * Command to start image capture now.
       
   390  * @sa handleCameraEvent
   430  */
   391  */
   431 void CxeStillCaptureControlSymbian::capture()
   392 void CxeStillCaptureControlSymbian::capture()
   432 {
   393 {
   433     CX_DEBUG_ENTER_FUNCTION();
   394     CX_DEBUG_ENTER_FUNCTION();
   434     CX_ASSERT_ALWAYS(mCameraDevice.camera());
   395     CX_ASSERT_ALWAYS(mCameraDevice.camera());
   435 
   396 
   436     // Start the image capture as fast as possible to minimize lag.
   397     // Start the image capture as fast as possible to minimize lag.
   437     // Check e.g. space available *after* this.
   398     // Check e.g. space available *after* this.
       
   399     // Capture sound will be played when we receive "image capture event" from ECAM.
   438     mCameraDevice.camera()->CaptureImage();
   400     mCameraDevice.camera()->CaptureImage();
   439 
   401 
   440     if (imagesLeft() > 0) {
   402     if (imagesLeft() > 0) {
   441         mCaptureSoundPlayer->play();
       
   442         setState(Capturing);
   403         setState(Capturing);
   443 
   404 
   444         //! @todo: NOTE: This call may not stay here. It can move depending on the implementation for burst capture.
   405         //! @todo: NOTE: This call may not stay here. It can move depending on the implementation for burst capture.
   445         if (mMode == BurstCapture) {
   406         if (mMode == BurstCapture) {
   446             // Start a new filename sequence
   407             // Start a new filename sequence
   462 
   423 
   463     CX_DEBUG_EXIT_FUNCTION();
   424     CX_DEBUG_EXIT_FUNCTION();
   464 }
   425 }
   465 
   426 
   466 
   427 
   467 /* !
   428 /*!
   468 @Param cameraIndex indicates which camera we are in use, primary/secondary
   429 @Param cameraIndex indicates which camera we are in use, primary/secondary
   469 Returns the format we use for specific camera index.
   430 Returns the format we use for specific camera index.
   470 */
   431 */
   471 CCamera::TFormat CxeStillCaptureControlSymbian::supportedStillFormat(Cxe::CameraIndex cameraIndex)
   432 CCamera::TFormat CxeStillCaptureControlSymbian::supportedStillFormat(Cxe::CameraIndex cameraIndex)
   472 {
   433 {
   479     CX_DEBUG_EXIT_FUNCTION();
   440     CX_DEBUG_EXIT_FUNCTION();
   480 
   441 
   481     return imgFormat;
   442     return imgFormat;
   482 }
   443 }
   483 
   444 
   484 
   445 /*!
   485 /**
       
   486  * Camera events. Only relevant one(s) are handled.
       
   487  */
       
   488 void CxeStillCaptureControlSymbian::handleCameraEvent(int eventUid, int error)
       
   489 {
       
   490     CX_DEBUG_ENTER_FUNCTION();
       
   491 
       
   492     if (eventUid == KUidECamEventSnapshotUidValue &&
       
   493         mCameraDeviceControl.mode() == Cxe::ImageMode) {
       
   494         handleSnapshotEvent(CxeErrorHandlingSymbian::map(error));
       
   495     }
       
   496 
       
   497     CX_DEBUG_EXIT_FUNCTION();
       
   498 }
       
   499 
       
   500 /**
       
   501  * Snapshot ready notification. Ask the snapshot from snapshot interface.
   446  * Snapshot ready notification. Ask the snapshot from snapshot interface.
   502  * NB: Typically snapshot arrives before image data but can be in reverse
   447  * NB: Typically snapshot arrives before image data but can be in reverse
   503  * order as well.
   448  * order as well.
   504  */
   449  *
   505 void CxeStillCaptureControlSymbian::handleSnapshotEvent(CxeError::Id error)
   450  * @param status Status of snapshot creation. CxeError::None if no error, otherwise contains the error code.
   506 {
   451  * @param snapshot Snapshot as QImage
   507     CX_DEBUG_ENTER_FUNCTION();
   452  */
   508 
   453 void CxeStillCaptureControlSymbian::handleSnapshotReady(CxeError::Id status, const QImage &snapshot)
   509     if (state() == CxeStillCaptureControl::Uninitialized) {
   454 {
   510         // we ignore this event, when we are not active
   455     CX_DEBUG_ENTER_FUNCTION();
   511         return;
   456     if (mCameraDeviceControl.mode() == Cxe::ImageMode) {
   512     }
   457 
   513 
   458         OstTrace0(camerax_performance, CXESTILLCAPTURECONTROL_HANDLESNAPSHOT_1, "msg: e_CX_HANDLE_SNAPSHOT 1");
   514     OstTrace0( camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_HANDLESNAPSHOTEVENT, "msg: e_CX_HANDLE_SNAPSHOT 1" );
   459 
   515 
   460         QPixmap ss = QPixmap::fromImage(snapshot);
   516     // Get image container for current snapshot index.
   461         // Get image container for current snapshot index.
   517     // Remember to increment counter.
   462         // Remember to increment counter.
   518     CxeStillImageSymbian* stillImage = getImageForIndex(mNextSnapshotIndex++);
   463         CxeStillImageSymbian* stillImage = getImageForIndex(mNextSnapshotIndex++);
   519 
   464         if (status == CxeError::None) {
   520     if (error == CxeError::None) {
   465             stillImage->setSnapshot(ss);
   521         try {
   466         }
   522             stillImage->setSnapshot(extractSnapshot());
   467 
   523         } catch (const std::exception& ex) {
   468         // Emit snapshotReady signal in all cases (error or not)
   524             error = CxeError::General;
   469         emit snapshotReady(status, snapshot, stillImage->id());
   525         }
   470 
   526     }
   471         // When the snapshot ready event is handled, prepare new filename.
   527 
   472         if (stillImage->filename().isEmpty()) {
   528     // Emit snapshotReady signal in all cases (error or not)
   473             // Error ignored at this point, try again when image data arrives.
   529     emit snapshotReady(error, stillImage->snapshot(), stillImage->id());
   474             prepareFilename(stillImage);
   530 
   475         }
   531     // When the snapshot ready event is handled, prepare new filename.
   476 
   532     if (stillImage->filename().isEmpty()) {
   477         OstTrace0(camerax_performance, CXESTILLCAPTURECONTROL_HANDLESNAPSHOT_2, "msg: e_CX_HANDLE_SNAPSHOT 0");
   533         // Error ignored at this point, try again when image data arrives.
   478     }
   534         prepareFilename(stillImage);
   479 
   535     }
   480     CX_DEBUG_EXIT_FUNCTION();
   536 
   481 }
   537     OstTrace0( camerax_performance, DUP1_CXESTILLCAPTURECONTROLSYMBIAN_HANDLESNAPSHOTEVENT, "msg: e_CX_HANDLE_SNAPSHOT 0" );
   482 
   538     CX_DEBUG_EXIT_FUNCTION();
   483 /*!
   539 }
   484 * Handle ECAM events.
   540 
   485 * Needed only for capture sound synchronization.
   541 /**
   486 * @param eventUid ECAM event id.
   542 * Gets QPixmap snapshot from ECAM buffer, if available.
   487 * @param error Error code. KErrNone if operation has been successful.
   543 * @param buffer ECAM buffer containing the snapshot data. Will be released when this
   488 */
   544 * method returns, even on exception.
   489 void CxeStillCaptureControlSymbian::handleCameraEvent(int eventUid, int error)
   545 */
   490 {
   546 QPixmap CxeStillCaptureControlSymbian::extractSnapshot()
   491     if (eventUid == KUidECamEventImageCaptureEventUidValue && error == KErrNone) {
   547 {
   492         CX_DEBUG(("CxeStillCaptureControlSymbian::handleCameraEvent - image capture event"));
   548     CX_DEBUG_ENTER_FUNCTION();
   493         if (state() == CxeStillCaptureControl::Capturing) {
   549     QPixmap pixmap;
   494             mCaptureSoundPlayer->play();
   550 
   495         }
   551     if (mCameraDevice.cameraSnapshot()) {
   496     }
   552 
   497 }
   553         QT_TRAP_THROWING({
   498 
   554             RArray<TInt> frameIndex;
   499 
   555             CleanupClosePushL(frameIndex);
   500 /*!
   556 
       
   557             MCameraBuffer &buffer(mCameraDevice.cameraSnapshot()->SnapshotDataL(frameIndex));
       
   558 
       
   559             // Make sure buffer is released on leave / exception
       
   560             CxeCameraBufferCleanup cleaner(&buffer);
       
   561             TInt firstImageIndex(frameIndex.Find(0));
       
   562             CFbsBitmap &snapshot(buffer.BitmapL(firstImageIndex));
       
   563 
       
   564             CleanupStack::PopAndDestroy(); // frameIndex
       
   565 
       
   566             TSize size = snapshot.SizeInPixels();
       
   567             TInt sizeInWords = size.iHeight * CFbsBitmap::ScanLineLength(size.iWidth, EColor16MU) / sizeof(TUint32);
       
   568             CX_DEBUG(("size %d x %d, sizeInWords = %d", size.iWidth, size.iHeight, sizeInWords ));
       
   569 
       
   570             TUint32* pixelData = new (ELeave) TUint32[ sizeInWords ];
       
   571             // Convert to QImage
       
   572             snapshot.LockHeap();
       
   573             TUint32* dataPtr = snapshot.DataAddress();
       
   574             memcpy(pixelData, dataPtr, sizeof(TUint32)*sizeInWords);
       
   575             snapshot.UnlockHeap();
       
   576 
       
   577             CX_DEBUG(("Creating QImage"));
       
   578             QImage *snapImage = new QImage((uchar*)pixelData, size.iWidth, size.iHeight,
       
   579                                            CFbsBitmap::ScanLineLength(size.iWidth, EColor16MU),
       
   580                                            QImage::Format_RGB32);
       
   581 
       
   582             pixmap = QPixmap::fromImage(*snapImage);
       
   583             delete [] pixelData;
       
   584             delete snapImage;
       
   585         });
       
   586     }
       
   587 
       
   588     CX_DEBUG_EXIT_FUNCTION();
       
   589     return pixmap;
       
   590 }
       
   591 
       
   592 /**
       
   593  * handleImageData: Image data received from ECam
   501  * handleImageData: Image data received from ECam
   594  */
   502  */
   595 void CxeStillCaptureControlSymbian::handleImageData(MCameraBuffer* cameraBuffer, int error)
   503 void CxeStillCaptureControlSymbian::handleImageData(MCameraBuffer* cameraBuffer, int error)
   596 {
   504 {
   597     CX_DEBUG_ENTER_FUNCTION();
   505     CX_DEBUG_ENTER_FUNCTION();
   636     if (!symbErr) {
   544     if (!symbErr) {
   637         //! @todo: this does a deep copy... we want to avoid this for performance/memory consumption reasons
   545         //! @todo: this does a deep copy... we want to avoid this for performance/memory consumption reasons
   638         QByteArray byteArray( reinterpret_cast<const char*>( data->Ptr() ), data->Size() );
   546         QByteArray byteArray( reinterpret_cast<const char*>( data->Ptr() ), data->Size() );
   639         data = NULL;
   547         data = NULL;
   640 
   548 
       
   549         // get geotagging setting value and check if we have to add location trail to image data.
       
   550         int value = Cxe::GeoTaggingOff;
       
   551         mSettings.get(CxeSettingIds::GEOTAGGING, value);
       
   552 
   641         // Save the image data
   553         // Save the image data
   642         CxeImageDataItemSymbian* dataItem = mImageDataQueue->startSave(byteArray, stillImage->filename(), stillImage->id());
   554         CxeImageDataItemSymbian* dataItem = mImageDataQueue->startSave(byteArray,
       
   555                                                                        stillImage->filename(),
       
   556                                                                        stillImage->id(),
       
   557                                                                        value == Cxe::GeoTaggingOn);
   643         stillImage->setDataItem(dataItem);
   558         stillImage->setDataItem(dataItem);
   644         mFileSaveThread.save(dataItem); // Saving thread takes ownership of dataItem.
   559         mFileSaveThread.save(dataItem); // Saving thread takes ownership of dataItem.
   645     }
   560     }
   646 
   561 
   647     // ECam Camera buffer should always be released
   562     // ECam Camera buffer should always be released
   658 
   573 
   659     CX_DEBUG_EXIT_FUNCTION();
   574     CX_DEBUG_EXIT_FUNCTION();
   660 }
   575 }
   661 
   576 
   662 
   577 
   663 /**
   578 /*!
   664  * Settings changed, needs updated
   579  * Settings changed, needs updated
   665  */
   580  */
   666 void CxeStillCaptureControlSymbian::handleSettingValueChanged(const QString& settingId, QVariant newValue)
   581 void CxeStillCaptureControlSymbian::handleSettingValueChanged(const QString& settingId, QVariant newValue)
   667 {
   582 {
   668     CX_DEBUG_ENTER_FUNCTION();
   583     CX_DEBUG_ENTER_FUNCTION();
   703     }
   618     }
   704 
   619 
   705     CX_DEBUG_EXIT_FUNCTION();
   620     CX_DEBUG_EXIT_FUNCTION();
   706 }
   621 }
   707 
   622 
   708 /**
   623 /*!
   709  * ECam reference changing, release resources
   624  * ECam reference changing, release resources
   710  */
   625  */
   711 void CxeStillCaptureControlSymbian::prepareForCameraDelete()
   626 void CxeStillCaptureControlSymbian::prepareForCameraDelete()
   712 {
   627 {
   713     CX_DEBUG_ENTER_FUNCTION();
   628     CX_DEBUG_ENTER_FUNCTION();
   714     deinit();
   629     deinit();
   715     CX_DEBUG_EXIT_FUNCTION();
   630     CX_DEBUG_EXIT_FUNCTION();
   716 }
   631 }
   717 
   632 
   718 /**
   633 /*!
   719  * Camera being released. Cancel ongoing capture, if any.
   634  * Camera being released. Cancel ongoing capture, if any.
   720  */
   635  */
   721 void CxeStillCaptureControlSymbian::prepareForRelease()
   636 void CxeStillCaptureControlSymbian::prepareForRelease()
   722 {
   637 {
   723     CX_DEBUG_ENTER_FUNCTION();
   638     CX_DEBUG_ENTER_FUNCTION();
   724     deinit();
   639     deinit();
   725     CX_DEBUG_EXIT_FUNCTION();
   640     CX_DEBUG_EXIT_FUNCTION();
   726 }
   641 }
   727 
   642 
   728 /**
   643 /*!
   729  *  New camera available,
   644  *  New camera available,
   730  */
   645  */
   731 void CxeStillCaptureControlSymbian::handleCameraAllocated(CxeError::Id error)
   646 void CxeStillCaptureControlSymbian::handleCameraAllocated(CxeError::Id error)
   732 {
   647 {
   733     CX_DEBUG_ENTER_FUNCTION();
   648     CX_DEBUG_ENTER_FUNCTION();
   757     }
   672     }
   758 
   673 
   759     CX_DEBUG_EXIT_FUNCTION();
   674     CX_DEBUG_EXIT_FUNCTION();
   760 }
   675 }
   761 
   676 
   762 /**
   677 /*!
   763  * Return number of images captured (during current capture operation only).
   678  * Return number of images captured (during current capture operation only).
   764  */
   679  */
   765 int CxeStillCaptureControlSymbian::imageCount() const
   680 int CxeStillCaptureControlSymbian::imageCount() const
   766 {
   681 {
   767     return mImages.count();
   682     return mImages.count();
   768 }
   683 }
   769 
   684 
   770 /**
   685 /*!
   771  * Reset the image array.
   686  * Reset the image array.
   772  */
   687  */
   773 void CxeStillCaptureControlSymbian::reset()
   688 void CxeStillCaptureControlSymbian::reset()
   774 {
   689 {
   775     CX_DEBUG_ENTER_FUNCTION();
   690     CX_DEBUG_ENTER_FUNCTION();
   781     mNextImageDataIndex = 0;
   696     mNextImageDataIndex = 0;
   782 
   697 
   783     CX_DEBUG_EXIT_FUNCTION();
   698     CX_DEBUG_EXIT_FUNCTION();
   784 }
   699 }
   785 
   700 
   786 /**
   701 /*!
   787  * This should cancel any ongoing image captures.
   702  * This should cancel any ongoing image captures.
   788  */
   703  */
   789 void CxeStillCaptureControlSymbian::cancelAll()
   704 void CxeStillCaptureControlSymbian::cancelAll()
   790 {
   705 {
   791     mImageDataQueue->clear();
   706     mImageDataQueue->clear();
   792     reset();
   707     reset();
   793 }
   708 }
   794 
   709 
   795 /**
   710 /*!
   796  * Sets the current capture mode: SingleImageCapture / BurstCapture.
   711  * Sets the current capture mode: SingleImageCapture / BurstCapture.
   797  */
   712  */
   798 void CxeStillCaptureControlSymbian::setMode( CaptureMode mode )
   713 void CxeStillCaptureControlSymbian::setMode( CaptureMode mode )
   799 {
   714 {
   800     mMode = mode;
   715     mMode = mode;
   801 }
   716 }
   802 
   717 
   803 /**
   718 /*!
   804  * Returns the current capture mode.
   719  * Returns the current capture mode.
   805  */
   720  */
   806 CxeStillCaptureControl::CaptureMode CxeStillCaptureControlSymbian::mode() const
   721 CxeStillCaptureControl::CaptureMode CxeStillCaptureControlSymbian::mode() const
   807 {
   722 {
   808     return mMode;
   723     return mMode;
   809 }
   724 }
   810 
   725 
   811 /**
   726 /*!
   812  * Operator [] - returns the indexed image from capture array.
   727  * Operator [] - returns the indexed image from capture array.
   813  */
   728  */
   814 CxeStillImage &CxeStillCaptureControlSymbian::operator[]( int index )
   729 CxeStillImage &CxeStillCaptureControlSymbian::operator[]( int index )
   815 {
   730 {
   816     return *mImages[ index ];
   731     return *mImages[ index ];
   817 }
   732 }
   818 
   733 
   819 /**
   734 /*!
   820  * Getter for image data queue.
   735  * Getter for image data queue.
   821  */
   736  */
   822 CxeImageDataQueue &CxeStillCaptureControlSymbian::imageDataQueue()
   737 CxeImageDataQueue &CxeStillCaptureControlSymbian::imageDataQueue()
   823 {
   738 {
   824     return *mImageDataQueue;
   739     return *mImageDataQueue;
   825 }
   740 }
   826 
   741 
   827 /**
   742 /*!
   828  * Generates a filename and sets it in the still image object.
   743  * Generates a filename and sets it in the still image object.
   829  * Skips the process if filename already copied exists in the object. This
   744  * Skips the process if filename already copied exists in the object. This
   830  * behaviour is required in rare cases where image data arrives before snapshot.
   745  * behaviour is required in rare cases where image data arrives before snapshot.
   831  */
   746  */
   832 CxeError::Id
   747 CxeError::Id
   833 CxeStillCaptureControlSymbian::prepareFilename(CxeStillImageSymbian *stillImage)
   748 CxeStillCaptureControlSymbian::prepareFilename(CxeStillImageSymbian *stillImage)
   834 {
   749 {
       
   750     OstTrace0(camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_PREPAREFILENAME_1, "msg: e_CX_PREPARE_FILENAME 1" );
       
   751 
   835     CxeError::Id err = CxeError::None;
   752     CxeError::Id err = CxeError::None;
   836     if (stillImage->filename().isEmpty()) {
   753     if (stillImage->filename().isEmpty()) {
   837         QString path;
   754         QString path;
   838 
   755 
   839         QString fileExt = mCurrentImageDetails.mImageFileExtension;
   756         QString fileExt = mCurrentImageDetails.mImageFileExtension;
   853             //! @todo: Error ID can be returned by this function.
   770             //! @todo: Error ID can be returned by this function.
   854             // Also error can be detected from empty filename string.
   771             // Also error can be detected from empty filename string.
   855             CX_DEBUG(("ERROR in filename generation. err:%d", err));
   772             CX_DEBUG(("ERROR in filename generation. err:%d", err));
   856         }
   773         }
   857     }
   774     }
       
   775 
       
   776     OstTrace0(camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_PREPAREFILENAME_2, "msg: e_CX_PREPARE_FILENAME 0" );
   858     return err;
   777     return err;
   859 }
   778 }
   860 
   779 
   861 /*!
   780 /*!
   862 * Helper method to set orientation data from the orientation sensor
   781 * Helper method to set orientation data from the orientation sensor
   885     }
   804     }
   886 
   805 
   887     CX_DEBUG_EXIT_FUNCTION();
   806     CX_DEBUG_EXIT_FUNCTION();
   888 }
   807 }
   889 
   808 
   890 /**
   809 /*!
   891  * Get the image container at given index or create a new one if needed.
   810  * Get the image container at given index or create a new one if needed.
   892  */
   811  */
   893 CxeStillImageSymbian* CxeStillCaptureControlSymbian::getImageForIndex(int index)
   812 CxeStillImageSymbian* CxeStillCaptureControlSymbian::getImageForIndex(int index)
   894 {
   813 {
   895     CxeStillImageSymbian* image(NULL);
   814     CxeStillImageSymbian* image(NULL);
   919     mAfState = newState;
   838     mAfState = newState;
   920     CxeAutoFocusControl::Mode mode = mAutoFocusControl.mode();
   839     CxeAutoFocusControl::Mode mode = mAutoFocusControl.mode();
   921 
   840 
   922     // if focused and in correct mode, play sound
   841     // if focused and in correct mode, play sound
   923     if  (newState == CxeAutoFocusControl::Ready &&
   842     if  (newState == CxeAutoFocusControl::Ready &&
   924          mode != CxeAutoFocusControl::Hyperfocal &&
   843          !mAutoFocusControl.isFixedFocusMode(mode) &&
   925          mode != CxeAutoFocusControl::Infinity &&
       
   926          mAutoFocusControl.isSoundEnabled()) {
   844          mAutoFocusControl.isSoundEnabled()) {
   927         mAutoFocusSoundPlayer->play();
   845         mAutoFocusSoundPlayer->play();
   928     }
   846     }
   929     CX_DEBUG_EXIT_FUNCTION();
   847     CX_DEBUG_EXIT_FUNCTION();
   930 }
   848 }