camerauis/cameraxui/cxengine/src/cxestillcapturecontrolsymbian.cpp
changeset 38 0f0b4c1d7744
parent 28 3075d9b614e6
child 39 c5025ea871a1
equal deleted inserted replaced
28:3075d9b614e6 38:0f0b4c1d7744
    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;
       
    57 }
    59 
    58 
    60 /**
    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 QPixmap&)),
   121             this, SLOT(handleCameraEvent(int,int)));
   122             this, SLOT(handleSnapshotReady(CxeError::Id, const QPixmap&)));
   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);
   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_STILL_CAPCONT_DEINIT 0" );
   233     CX_DEBUG_EXIT_FUNCTION();
   233     CX_DEBUG_EXIT_FUNCTION();
   234 }
   234 }
   330  Returns symbian error code.
   330  Returns symbian error code.
   331  */
   331  */
   332 int CxeStillCaptureControlSymbian::prepareStillSnapshot()
   332 int CxeStillCaptureControlSymbian::prepareStillSnapshot()
   333 {
   333 {
   334     CX_DEBUG_ENTER_FUNCTION();
   334     CX_DEBUG_ENTER_FUNCTION();
   335 
   335     OstTrace0( camerax_performance, DUP4_CXESTILLCAPTURECONTROLSYMBIAN_PREPARE, "msg: e_CX_PREPARE_SNAPSHOT 1" );
   336     CCamera::CCameraSnapshot *cameraSnapshot = mCameraDevice.cameraSnapshot();
   336 
   337     CX_ASSERT_ALWAYS(cameraSnapshot);
   337     int status(KErrNone);
   338 
   338     try {
   339     int err = KErrNone;
   339         QSize snapshotSize = mSnapshotControl.calculateSnapshotSize(
   340     // Whether or not we have postcapture on, we need the snapshot for Thumbnail Manager.
   340                                 mViewfinderControl.deviceDisplayResolution(),
   341     if (cameraSnapshot) {
   341                                 QSize(mCurrentImageDetails.mWidth, mCurrentImageDetails.mHeight));
   342         // Cancel active snapshot
   342         mSnapshotControl.start(snapshotSize);
   343         cameraSnapshot->StopSnapshot();
   343     } catch (...) {
   344 
   344         status = KErrGeneral;
   345         // Prepare snapshot
   345     }
   346         CCamera::TFormat snapFormat = CCamera::EFormatFbsBitmapColor16MU;
   346     OstTrace0( camerax_performance, DUP5_CXESTILLCAPTURECONTROLSYMBIAN_PREPARE, "msg: e_CX_PREPARE_SNAPSHOT 0" );
   347         OstTrace0( camerax_performance, DUP4_CXESTILLCAPTURECONTROLSYMBIAN_PREPARE, "msg: e_CX_PREPARE_SNAPSHOT 1" );
   347 
   348         TRAP(err, cameraSnapshot->PrepareSnapshotL(snapFormat,
   348     CX_DEBUG_EXIT_FUNCTION();
   349                                                    getSnapshotSize(),
   349     return status;
   350                                                    KMaintainAspectRatio));
       
   351         OstTrace0( camerax_performance, DUP5_CXESTILLCAPTURECONTROLSYMBIAN_PREPARE, "msg: e_CX_PREPARE_SNAPSHOT 0" );
       
   352         CX_DEBUG(("PrepareSnapshotL done, err=%d", err));
       
   353 
       
   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 }
   350 }
   369 
   351 
   370 
   352 
   371 /**!
   353 /**!
   372  imageInfo contains image qualities details
   354  imageInfo contains image qualities details
   398 
   380 
   399     CX_DEBUG_EXIT_FUNCTION();
   381     CX_DEBUG_EXIT_FUNCTION();
   400     return err;
   382     return err;
   401 }
   383 }
   402 
   384 
   403 
       
   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 /**
   385 /**
   429  * Command to start image capture now.
   386  * Command to start image capture now.
   430  */
   387  */
   431 void CxeStillCaptureControlSymbian::capture()
   388 void CxeStillCaptureControlSymbian::capture()
   432 {
   389 {
   479     CX_DEBUG_EXIT_FUNCTION();
   436     CX_DEBUG_EXIT_FUNCTION();
   480 
   437 
   481     return imgFormat;
   438     return imgFormat;
   482 }
   439 }
   483 
   440 
   484 
       
   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 /**
   441 /**
   501  * Snapshot ready notification. Ask the snapshot from snapshot interface.
   442  * Snapshot ready notification. Ask the snapshot from snapshot interface.
   502  * NB: Typically snapshot arrives before image data but can be in reverse
   443  * NB: Typically snapshot arrives before image data but can be in reverse
   503  * order as well.
   444  * order as well.
   504  */
   445  */
   505 void CxeStillCaptureControlSymbian::handleSnapshotEvent(CxeError::Id error)
   446 void CxeStillCaptureControlSymbian::handleSnapshotReady(CxeError::Id status, const QPixmap& snapshot)
   506 {
   447 {
   507     CX_DEBUG_ENTER_FUNCTION();
   448     CX_DEBUG_ENTER_FUNCTION();
   508 
   449     if (mCameraDeviceControl.mode() == Cxe::ImageMode) {
   509     if (state() == CxeStillCaptureControl::Uninitialized) {
   450 
   510         // we ignore this event, when we are not active
   451         OstTrace0( camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_HANDLESNAPSHOTEVENT, "msg: e_CX_HANDLE_SNAPSHOT 1" );
   511         return;
   452 
   512     }
   453         // Get image container for current snapshot index.
   513 
   454         // Remember to increment counter.
   514     OstTrace0( camerax_performance, CXESTILLCAPTURECONTROLSYMBIAN_HANDLESNAPSHOTEVENT, "msg: e_CX_HANDLE_SNAPSHOT 1" );
   455         CxeStillImageSymbian* stillImage = getImageForIndex(mNextSnapshotIndex++);
   515 
   456         if (status == CxeError::None) {
   516     // Get image container for current snapshot index.
   457             stillImage->setSnapshot(snapshot);
   517     // Remember to increment counter.
   458         }
   518     CxeStillImageSymbian* stillImage = getImageForIndex(mNextSnapshotIndex++);
   459 
   519 
   460         // Emit snapshotReady signal in all cases (error or not)
   520     if (error == CxeError::None) {
   461         emit snapshotReady(status, snapshot, stillImage->id());
   521         try {
   462 
   522             stillImage->setSnapshot(extractSnapshot());
   463         // When the snapshot ready event is handled, prepare new filename.
   523         } catch (const std::exception& ex) {
   464         if (stillImage->filename().isEmpty()) {
   524             error = CxeError::General;
   465             // Error ignored at this point, try again when image data arrives.
   525         }
   466             prepareFilename(stillImage);
   526     }
   467         }
   527 
   468 
   528     // Emit snapshotReady signal in all cases (error or not)
   469         OstTrace0( camerax_performance, DUP1_CXESTILLCAPTURECONTROLSYMBIAN_HANDLESNAPSHOTEVENT, "msg: e_CX_HANDLE_SNAPSHOT 0" );
   529     emit snapshotReady(error, stillImage->snapshot(), stillImage->id());
   470     }
   530 
   471 
   531     // When the snapshot ready event is handled, prepare new filename.
   472     CX_DEBUG_EXIT_FUNCTION();
   532     if (stillImage->filename().isEmpty()) {
       
   533         // Error ignored at this point, try again when image data arrives.
       
   534         prepareFilename(stillImage);
       
   535     }
       
   536 
       
   537     OstTrace0( camerax_performance, DUP1_CXESTILLCAPTURECONTROLSYMBIAN_HANDLESNAPSHOTEVENT, "msg: e_CX_HANDLE_SNAPSHOT 0" );
       
   538     CX_DEBUG_EXIT_FUNCTION();
       
   539 }
       
   540 
       
   541 /**
       
   542 * Gets QPixmap snapshot from ECAM buffer, if available.
       
   543 * @param buffer ECAM buffer containing the snapshot data. Will be released when this
       
   544 * method returns, even on exception.
       
   545 */
       
   546 QPixmap CxeStillCaptureControlSymbian::extractSnapshot()
       
   547 {
       
   548     CX_DEBUG_ENTER_FUNCTION();
       
   549     QPixmap pixmap;
       
   550 
       
   551     if (mCameraDevice.cameraSnapshot()) {
       
   552 
       
   553         QT_TRAP_THROWING({
       
   554             RArray<TInt> frameIndex;
       
   555             CleanupClosePushL(frameIndex);
       
   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 }
   473 }
   591 
   474 
   592 /**
   475 /**
   593  * handleImageData: Image data received from ECam
   476  * handleImageData: Image data received from ECam
   594  */
   477  */