camerauis/cameraxui/cxengine/src/cxevideocapturecontrolsymbian.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".
    12 * Contributors:
    12 * Contributors:
    13 *
    13 *
    14 * Description:
    14 * Description:
    15 *
    15 *
    16 */
    16 */
       
    17 
       
    18 #include <algorithm>
       
    19 #include <exception>
    17 #include <QTime>
    20 #include <QTime>
    18 #include <fbs.h>
       
    19 #include <QPixmap>
    21 #include <QPixmap>
    20 #include <coemain.h>
    22 #include <coemain.h>
    21 #include <QStringList>
    23 #include <QStringList>
    22 #include <AudioPreference.h>
    24 
    23 
    25 #include "cxeexception.h"
    24 #include "cxevideocapturecontrolsymbian.h"
    26 #include "cxevideocapturecontrolsymbian.h"
    25 #include "cxevideorecorderutilitysymbian.h"
    27 #include "cxevideorecorderutilitysymbian.h"
    26 #include "cxecameradevicecontrolsymbian.h"
    28 #include "cxecameradevicecontrolsymbian.h"
    27 #include "cxefilenamegeneratorsymbian.h"
    29 #include "cxefilenamegeneratorsymbian.h"
    28 #include "cxeerrormappingsymbian.h"
    30 #include "cxeerrormappingsymbian.h"
    29 #include "cxeviewfindercontrol.h"
    31 #include "cxeviewfindercontrol.h"
       
    32 #include "cxesnapshotcontrol.h"
    30 #include "cxestillimagesymbian.h"
    33 #include "cxestillimagesymbian.h"
    31 #include "cxecameradevice.h"
    34 #include "cxecameradevice.h"
    32 #include "cxutils.h"
    35 #include "cxutils.h"
    33 #include "cxestate.h"
    36 #include "cxestate.h"
    34 #include "cxesettings.h"
    37 #include "cxesettings.h"
    45 
    48 
    46 
    49 
    47 // constants
    50 // constants
    48 namespace
    51 namespace
    49 {
    52 {
    50     // Controller UId, can be used by the client to identify the controller, e.g. if the custom command can be used
       
    51     const TUid KCamCControllerImplementationUid = {0x101F8503};
       
    52     // TMMFEvent UIDs for Async stop
    53     // TMMFEvent UIDs for Async stop
    53     const TUid KCamCControllerCCVideoRecordStopped = {0x2000E546};
    54     const TUid KCamCControllerCCVideoRecordStopped = {0x2000E546};
    54     const TUid KCamCControllerCCVideoFileComposed = {0x2000E547};
    55     const TUid KCamCControllerCCVideoFileComposed = {0x2000E547};
    55 
    56 
    56     // Custom command for setting a new filename without closing & reopening the controller
       
    57     enum TCamCControllerCustomCommands
       
    58         {
       
    59         ECamCControllerCCNewFilename = 0,
       
    60         ECamCControllerCCVideoStopAsync
       
    61         };
       
    62 
       
    63     const TInt    KOneSecond                  = 1000000;
       
    64     const int     KMaintainAspectRatio        = false;
       
    65     const TInt64  KMinRequiredSpaceVideo      = 4000000;
    57     const TInt64  KMinRequiredSpaceVideo      = 4000000;
    66     const uint    KOneMillion                 = 1000000;
       
    67     const qreal   KMetaDataCoeff              = 1.03;      // Coefficient to estimate metadata amount
       
    68     const uint    KCamCMaxClipDurationInSecs  = 5400;      // Maximun video clip duration in seconds
       
    69     const qreal   KCMRAvgVideoBitRateScaler   = 0.9;       // avg video bit rate scaler
       
    70 }
    58 }
    71 
    59 
    72 
    60 
    73 /*!
    61 /*!
    74 * CxeVideoCaptureControlSymbian::CxeVideoCaptureControlSymbian
    62 * CxeVideoCaptureControlSymbian::CxeVideoCaptureControlSymbian
    75 */
    63 */
    76 CxeVideoCaptureControlSymbian::CxeVideoCaptureControlSymbian(
    64 CxeVideoCaptureControlSymbian::CxeVideoCaptureControlSymbian(
    77     CxeCameraDevice &cameraDevice,
    65     CxeCameraDevice &cameraDevice,
    78     CxeViewfinderControl &viewfinderControl,
    66     CxeViewfinderControl &viewfinderControl,
       
    67     CxeSnapshotControl &snapshotControl,
    79     CxeCameraDeviceControl &cameraDeviceControl,
    68     CxeCameraDeviceControl &cameraDeviceControl,
    80     CxeFilenameGenerator &nameGenerator,
    69     CxeFilenameGenerator &nameGenerator,
    81     CxeSettings &settings,
    70     CxeSettings &settings,
    82     CxeQualityPresets &qualityPresets,
    71     CxeQualityPresets &qualityPresets,
    83     CxeDiskMonitor &diskMonitor)
    72     CxeDiskMonitor &diskMonitor)
    84     : CxeStateMachine("CxeVideoCaptureControlSymbian"),
    73     : CxeStateMachine("CxeVideoCaptureControlSymbian"),
    85       mVideoRecorder(NULL),
    74       mVideoRecorder(NULL),
    86       mCameraDevice(cameraDevice),
    75       mCameraDevice(cameraDevice),
    87       mCameraDeviceControl(cameraDeviceControl),
    76       mCameraDeviceControl(cameraDeviceControl),
    88       mViewfinderControl(viewfinderControl),
    77       mViewfinderControl(viewfinderControl),
       
    78       mSnapshotControl(snapshotControl),
    89       mFilenameGenerator(nameGenerator),
    79       mFilenameGenerator(nameGenerator),
    90       mSettings(settings),
    80       mSettings(settings),
    91       mQualityPresets(qualityPresets),
    81       mQualityPresets(qualityPresets),
    92       mDiskMonitor(diskMonitor),
    82       mDiskMonitor(diskMonitor),
    93       mSnapshot(),
    83       mSnapshot(),
    94       mNewFileName(""),
    84       mVideoStartSoundPlayer(NULL),
       
    85       mVideoStopSoundPlayer(NULL),
    95       mCurrentFilename("")
    86       mCurrentFilename("")
    96 {
    87 {
    97     CX_DEBUG_ENTER_FUNCTION();
    88     CX_DEBUG_ENTER_FUNCTION();
    98     OstTrace0(camerax_performance, CXEVIDEOCAPTURECONTROLSYMBIAN_CREATE_IN, "msg: e_CX_VIDEOCAPTURECONTROL_NEW 1");
    89     OstTrace0(camerax_performance, CXEVIDEOCAPTURECONTROLSYMBIAN_CREATE_IN, "msg: e_CX_VIDEOCAPTURECONTROL_NEW 1");
    99 
    90 
   100     qRegisterMetaType<CxeVideoCaptureControl::State> ();
    91     qRegisterMetaType<CxeVideoCaptureControl::State> ();
   101     initializeStates();
    92     initializeStates();
   102 
    93 
   103     mVideoStopSoundPlayer = new
    94     mVideoStopSoundPlayer = new
   104              CxeSoundPlayerSymbian(CxeSoundPlayerSymbian::VideoCaptureStop);
    95              CxeSoundPlayerSymbian(CxeSoundPlayerSymbian::VideoCaptureStop,
       
    96                                    mSettings);
   105     mVideoStartSoundPlayer = new
    97     mVideoStartSoundPlayer = new
   106              CxeSoundPlayerSymbian(CxeSoundPlayerSymbian::VideoCaptureStart);
    98              CxeSoundPlayerSymbian(CxeSoundPlayerSymbian::VideoCaptureStart,
       
    99                                    mSettings);
   107 
   100 
   108     // If camera is already allocated, call the slot ourselves.
   101     // If camera is already allocated, call the slot ourselves.
   109     if (mCameraDevice.camera()) {
   102     if (mCameraDevice.camera()) {
   110         handleCameraAllocated(CxeError::None);
   103         handleCameraAllocated(CxeError::None);
   111     }
   104     }
   116             this, SLOT(prepareForCameraDelete()));
   109             this, SLOT(prepareForCameraDelete()));
   117     connect(&cameraDevice, SIGNAL(prepareForRelease()),
   110     connect(&cameraDevice, SIGNAL(prepareForRelease()),
   118             this, SLOT(prepareForRelease()) );
   111             this, SLOT(prepareForRelease()) );
   119     connect(&cameraDevice, SIGNAL(cameraAllocated(CxeError::Id)),
   112     connect(&cameraDevice, SIGNAL(cameraAllocated(CxeError::Id)),
   120             this, SLOT(handleCameraAllocated(CxeError::Id)));
   113             this, SLOT(handleCameraAllocated(CxeError::Id)));
       
   114 
   121     // connect playing sound signals
   115     // connect playing sound signals
   122     connect(mVideoStartSoundPlayer, SIGNAL(playComplete(int)),
   116     connect(mVideoStartSoundPlayer, SIGNAL(playComplete(int)),
   123             this, SLOT(handleSoundPlayed()));
   117             this, SLOT(handleSoundPlayed()));
   124 
   118 
       
   119     // connect snapshot ready signal
       
   120     connect(&mSnapshotControl, SIGNAL(snapshotReady(CxeError::Id, const QImage&)),
       
   121             this, SLOT(handleSnapshotReady(CxeError::Id, const QImage&)));
       
   122 
   125     // enabling setting change callbacks to videocapturecontrol
   123     // enabling setting change callbacks to videocapturecontrol
   126     connect(&mSettings, SIGNAL(settingValueChanged(const QString&,QVariant)),
   124     connect(&mSettings, SIGNAL(settingValueChanged(const QString&,QVariant)),
   127             this, SLOT(handleSettingValueChanged(const QString&,QVariant)));
   125             this, SLOT(handleSettingValueChanged(const QString&,QVariant)));
   128 
   126     connect(&mSettings, SIGNAL(sceneChanged(CxeScene&)),
   129     connect(&mSettings, SIGNAL(sceneChanged(CxeScene&)), this, SLOT(handleSceneChanged(CxeScene&)));
   127             this, SLOT(handleSceneChanged(CxeScene&)));
   130 
       
   131     OstTrace0(camerax_performance, CXEVIDEOCAPTURECONTROLSYMBIAN_CREATE_M2, "msg: e_CX_ENGINE_CONNECT_SIGNALS 0");
   128     OstTrace0(camerax_performance, CXEVIDEOCAPTURECONTROLSYMBIAN_CREATE_M2, "msg: e_CX_ENGINE_CONNECT_SIGNALS 0");
   132 
   129 
   133     OstTrace0(camerax_performance, CXEVIDEOCAPTURECONTROLSYMBIAN_CREATE_OUT, "msg: e_CX_VIDEOCAPTURECONTROL_NEW 0");
   130     OstTrace0(camerax_performance, CXEVIDEOCAPTURECONTROLSYMBIAN_CREATE_OUT, "msg: e_CX_VIDEOCAPTURECONTROL_NEW 0");
   134     CX_DEBUG_EXIT_FUNCTION();
   131     CX_DEBUG_EXIT_FUNCTION();
   135 }
   132 }
   136 
       
   137 
   133 
   138 /*!
   134 /*!
   139 * CxeVideoCaptureControlSymbian::~CxeVideoCaptureControlSymbian()
   135 * CxeVideoCaptureControlSymbian::~CxeVideoCaptureControlSymbian()
   140 */
   136 */
   141 CxeVideoCaptureControlSymbian::~CxeVideoCaptureControlSymbian()
   137 CxeVideoCaptureControlSymbian::~CxeVideoCaptureControlSymbian()
   147     delete mVideoStartSoundPlayer;
   143     delete mVideoStartSoundPlayer;
   148     delete mVideoStopSoundPlayer;
   144     delete mVideoStopSoundPlayer;
   149 
   145 
   150     CX_DEBUG_EXIT_FUNCTION();
   146     CX_DEBUG_EXIT_FUNCTION();
   151 }
   147 }
   152 
       
   153 
   148 
   154 /*!
   149 /*!
   155 * Initializes resources for video recording.
   150 * Initializes resources for video recording.
   156 */
   151 */
   157 void CxeVideoCaptureControlSymbian::init()
   152 void CxeVideoCaptureControlSymbian::init()
   166         // video recorder already initalized. Continue to prepare video reocording.
   161         // video recorder already initalized. Continue to prepare video reocording.
   167         open();
   162         open();
   168     }
   163     }
   169 
   164 
   170     OstTrace0( camerax_performance, DUP1_CXEVIDEOCAPTURECONTROLSYMBIAN_INIT, "msg: e_CX_VIDEO_CAPCONT_INIT 0" );
   165     OstTrace0( camerax_performance, DUP1_CXEVIDEOCAPTURECONTROLSYMBIAN_INIT, "msg: e_CX_VIDEO_CAPCONT_INIT 0" );
   171 
   166     CX_DEBUG_EXIT_FUNCTION();
   172     CX_DEBUG_EXIT_FUNCTION();
   167 }
   173 }
   168 
   174 
   169 /*!
   175 
       
   176 /*
       
   177 * Releases all resources
   170 * Releases all resources
   178 */
   171 */
   179 void CxeVideoCaptureControlSymbian::deinit()
   172 void CxeVideoCaptureControlSymbian::deinit()
   180 {
   173 {
   181     CX_DEBUG_ENTER_FUNCTION();
   174     CX_DEBUG_ENTER_FUNCTION();
   182 
   175 
   183     if(state() == Idle) {
   176     // Nothing to do if already idle.
   184         // nothing to do
   177     if(state() != Idle) {
   185         return;
   178         OstTrace0( camerax_performance, CXEVIDEOCAPTURECONTROLSYMBIAN_DEINIT, "msg: e_CX_VIDEO_CAPCONT_DEINIT 1" );
   186     }
   179 
   187 
   180         // first stop viewfinder
   188     OstTrace0( camerax_performance, CXEVIDEOCAPTURECONTROLSYMBIAN_DEINIT, "msg: e_CX_VIDEO_CAPCONT_DEINIT 1" );
   181         mViewfinderControl.stop();
   189 
   182 
   190     // first stop viewfinder
   183         // stop video-recording in-case if its ongoing.
   191     mViewfinderControl.stop();
   184         stop();
   192 
   185 
   193     // stop video-recording in-case if its ongoing.
   186         // Check if state is stopping, in which case we have to inform the
   194     stop();
   187         // file harvester that a file is to be completed. We would not
   195 
   188         // call harvestFile otherwise in this case.
   196     if (mCameraDevice.cameraSnapshot()) {
   189         // Otherwise the video will not be found from videos app.
   197         mCameraDevice.cameraSnapshot()->StopSnapshot();
   190         if (state() == Stopping) {
   198     }
   191             emit videoComposed(CxeError::None, mCurrentFilename);
   199 
   192         }
   200     if (mVideoRecorder) {
   193 
   201         mVideoRecorder->Close();
   194         mSnapshotControl.stop();
   202     }
   195 
   203 
   196         if (mVideoRecorder) {
   204     // revert back the new filename to empty string so that we generate a new file name
   197             mVideoRecorder->close();
   205     // when we init again
   198         }
   206     mNewFileName = QString("");
   199 
   207 
   200         setState(Idle);
   208     setState(Idle);
   201 
   209 
   202         OstTrace0( camerax_performance, DUP1_CXEVIDEOCAPTURECONTROLSYMBIAN_DEINIT, "msg: e_CX_VIDEO_CAPCONT_DEINIT 0" );
   210     OstTrace0( camerax_performance, DUP1_CXEVIDEOCAPTURECONTROLSYMBIAN_DEINIT, "msg: e_CX_VIDEO_CAPCONT_DEINIT 0" );
   203     }
   211 
   204     CX_DEBUG_EXIT_FUNCTION();
   212     CX_DEBUG_EXIT_FUNCTION();
   205 }
   213 }
       
   214 
       
   215 
   206 
   216 /*!
   207 /*!
   217 * Intializes VideoRecorder for recording.
   208 * Intializes VideoRecorder for recording.
   218 */
   209 */
   219 void CxeVideoCaptureControlSymbian::initVideoRecorder()
   210 void CxeVideoCaptureControlSymbian::initVideoRecorder()
   220 {
   211 {
   221     CX_DEBUG_ENTER_FUNCTION();
   212     CX_DEBUG_ENTER_FUNCTION();
   222 
   213 
   223     if (state() != Idle) {
   214     // Init needed only in Idle state
   224         // not valid state to start "open" operation
   215     if (state() == Idle) {
   225         return;
   216         try {
   226     }
   217             // if video recorder is not created, do it now.
   227 
   218             createVideoRecorder();
   228     if(!mVideoRecorder) {
   219 
   229         // if video recorder is not created, do it now.
   220             // update current video quality details from icm.
   230         createVideoRecorder();
   221             // Throws an error if unable to get the quality.
   231     }
   222             getVideoQualityDetails(mCurrentVideoDetails);
   232 
   223 
   233     // update current video quality details from icm
   224             // Video recorder is ready to open video file for recording.
   234     CxeError::Id err = getVideoQualityDetails(mCurrentVideoDetails);
       
   235 
       
   236     if (!err) {
       
   237         // read videofile mime type
       
   238         QByteArray videoFileData =
       
   239                     mCurrentVideoDetails.mVideoFileMimeType.toLatin1();
       
   240         TPtrC8 videoFileMimeType(reinterpret_cast<const TUint8*>
       
   241                            (videoFileData.constData()), videoFileData.size());
       
   242 
       
   243         // read preferred supplier
       
   244         TPtrC16 supplier(reinterpret_cast<const TUint16*>
       
   245                            (mCurrentVideoDetails.mPreferredSupplier.utf16()));
       
   246 
       
   247         err = findVideoController(videoFileMimeType, supplier);
       
   248 
       
   249         if (!err) {
       
   250             // video recorder is ready to open video file for recording.
       
   251             setState(Initialized);
   225             setState(Initialized);
   252             open();
   226             open();
   253         }
   227         } catch (const std::exception &e) {
   254     } else {
   228             // Handle error
   255         err = CxeErrorHandlingSymbian::map(KErrNotReady);
   229             handlePrepareFailed();
   256     }
   230         }
   257 
   231     }
   258     if (err) {
   232 
   259         // In case of error
   233     CX_DEBUG_EXIT_FUNCTION();
   260         emit videoPrepareComplete(err);
   234 }
   261         deinit();
       
   262     }
       
   263 
       
   264     CX_DEBUG_EXIT_FUNCTION();
       
   265 }
       
   266 
       
   267 
       
   268 
   235 
   269 /*!
   236 /*!
   270 * Opens file for video recording.
   237 * Opens file for video recording.
   271 */
   238 */
   272 void CxeVideoCaptureControlSymbian::open()
   239 void CxeVideoCaptureControlSymbian::open()
   273 {
   240 {
   274     CX_DEBUG_ENTER_FUNCTION();
   241     CX_DEBUG_ENTER_FUNCTION();
   275 
   242 
   276     if (state() != Initialized) {
   243     // Check valid state to start "open" operation
   277         // not valid state to start "open" operation
   244     if (state() == Initialized) {
   278         return;
   245         try {
   279     }
   246             // generate video file name, if necessary
   280 
   247             generateFilename();
   281     CxeError::Id err = CxeError::None;
   248             CX_DEBUG(( "Next video file path: %s", mCurrentFilename.toAscii().constData() ));
   282 
   249 
   283     // generate video file name, if necessary
   250             // Start preparing..
   284     if (mNewFileName.isEmpty()) {
   251             setState(CxeVideoCaptureControl::Preparing);
   285         QStringList list = mCurrentVideoDetails.mVideoFileMimeType.split("/");
   252 
   286         QString fileExt(".");
   253             // Exception thrown if open fails.
   287         if (list.count() == 2) {
   254             mVideoRecorder->open(mCameraDevice.camera()->Handle(),
   288             fileExt = fileExt + list[1];
   255                                  mCurrentFilename,
   289         }
   256                                  mCurrentVideoDetails.mVideoFileMimeType,
   290         // Generate new filename and open the file for writing video data
   257                                  mCurrentVideoDetails.mPreferredSupplier,
   291         err = mFilenameGenerator.generateFilename(mNewFileName, fileExt);
   258                                  mCurrentVideoDetails.mVideoCodecMimeType,
   292         if (err == CxeError::None) {
   259                                  mCurrentVideoDetails.mAudioType);
   293             mCurrentFilename = mNewFileName;
   260         } catch (const std::exception &e) {
   294         } else {
   261             handlePrepareFailed();
   295             // file name is not valid, re-initialize the value of current string
   262         }
   296             // back to empty string
   263     }
   297             mCurrentFilename = QString("");
   264     CX_DEBUG_EXIT_FUNCTION();
   298         }
   265 }
   299     }
   266 
   300 
   267 /*!
   301     if (!err &&
   268 * Helper method for generating filename.
   302         mVideoRecorder &&
   269 * Throws exception, if file type mime is formatted wrong or
   303         !mCurrentFilename.isEmpty()) {
   270 * filename generation fails.
   304 
   271 */
   305         TPtrC16 fName(reinterpret_cast<const TUint16*>(mCurrentFilename.utf16()));
   272 void CxeVideoCaptureControlSymbian::generateFilename()
   306         CX_DEBUG(( "Next video file path: %s", mCurrentFilename.toAscii().constData() ));
   273 {
   307 
   274     CX_DEBUG_ENTER_FUNCTION();
   308         // read video codec mime type
   275     mCurrentFilename = QString("");
   309         QByteArray videoCodecData =
   276 
   310                     mCurrentVideoDetails.mVideoCodecMimeType.toLatin1();
   277     QStringList list = mCurrentVideoDetails.mVideoFileMimeType.split("/");
   311         TPtrC8 videoCodecMimeType(reinterpret_cast<const TUint8*>
   278     // Throw exception if mime string is formatted wrong.
   312                            (videoCodecData.constData()), videoCodecData.size());
   279     if (list.count() != 2) {
   313 
   280         throw new CxeException(CxeError::General);
   314         setState(CxeVideoCaptureControl::Preparing);
   281     }
   315 
   282     QString fileExt = "." + list[1];
   316         TRAPD(openErr, mVideoRecorder->OpenFileL(fName,
   283 
   317                        mCameraDevice.camera()->Handle(),
   284     // Generate new filename and open the file for writing video data
   318                        mVideoControllerUid,
   285     CxeException::throwIfError(mFilenameGenerator.generateFilename(mCurrentFilename, fileExt));
   319                        mVideoFormatUid,
   286 
   320                        videoCodecMimeType,
   287     CX_DEBUG_EXIT_FUNCTION();
   321                        audioType(mCurrentVideoDetails.mAudioType)));
   288 }
   322 
       
   323         err = CxeErrorHandlingSymbian::map(openErr);
       
   324     }
       
   325     if (err) {
       
   326         // error occured.
       
   327         deinit();
       
   328         emit videoPrepareComplete(err);
       
   329     }
       
   330     CX_DEBUG_EXIT_FUNCTION();
       
   331 }
       
   332 
       
   333 
       
   334 /*!
       
   335 * Prepare Video Recorder with necessary settings for video capture.
       
   336 */
       
   337 TFourCC CxeVideoCaptureControlSymbian::audioType(const QString& str)
       
   338 {
       
   339     CX_DEBUG_ENTER_FUNCTION();
       
   340 
       
   341     QByteArray audioType = str.toAscii();
       
   342 
       
   343     quint8 char1(' ');
       
   344     quint8 char2(' ');
       
   345     quint8 char3(' ');
       
   346     quint8 char4(' ');
       
   347 
       
   348     if (audioType.count() > 3) {
       
   349         char1 = audioType[0];
       
   350         char2 = audioType[1];
       
   351         char3 = audioType[2];
       
   352 
       
   353         if (audioType.count() == 4) {
       
   354             char4 = audioType[3];
       
   355         }
       
   356     }
       
   357 
       
   358     return TFourCC(char1, char2, char3, char4);
       
   359 }
       
   360 
       
   361 
   289 
   362 /*!
   290 /*!
   363 * Prepare Video Recorder with necessary settings for video capture.
   291 * Prepare Video Recorder with necessary settings for video capture.
   364 */
   292 */
   365 void CxeVideoCaptureControlSymbian::prepare()
   293 void CxeVideoCaptureControlSymbian::prepare()
   369     if (state() != Preparing) {
   297     if (state() != Preparing) {
   370         // not valid state to continue prepare.
   298         // not valid state to continue prepare.
   371         return;
   299         return;
   372     }
   300     }
   373 
   301 
   374     CX_DEBUG(("Video resoulution (%d,%d)", mCurrentVideoDetails.mWidth,
   302     OstTrace0(camerax_performance, CXEVIDEOCAPTURECONTROL_PREPARE_1, "msg: e_CX_VIDCAPCONT_PREPARE 1");
   375                                            mCurrentVideoDetails.mHeight));
   303     QSize frameSize(mCurrentVideoDetails.mWidth, mCurrentVideoDetails.mHeight);
   376     CX_DEBUG(("Video bitrate = %d)", mCurrentVideoDetails.mVideoBitRate));
       
   377 
       
   378     OstTrace0(camerax_performance, CXEVIDEOCAPTURECONTROLSYMBIAN_PREPARE, "msg: e_CX_VIDCAPCONT_PREPARE 1");
       
   379     TSize frameSize;
       
   380     frameSize.SetSize(mCurrentVideoDetails.mWidth, mCurrentVideoDetails.mHeight);
       
   381 
   304 
   382     int muteSetting = 0; // audio enabled
   305     int muteSetting = 0; // audio enabled
   383     mSettings.get(CxeSettingIds::VIDEO_MUTE_SETTING, muteSetting);
   306     mSettings.get(CxeSettingIds::VIDEO_MUTE_SETTING, muteSetting);
   384 
   307 
   385     // Check if scene defines frame rate.
   308     // Check if scene defines frame rate.
   388     mSettings.get(CxeSettingIds::FRAME_RATE, frameRate);
   311     mSettings.get(CxeSettingIds::FRAME_RATE, frameRate);
   389     if (frameRate <= 0) {
   312     if (frameRate <= 0) {
   390         frameRate = mCurrentVideoDetails.mVideoFrameRate;
   313         frameRate = mCurrentVideoDetails.mVideoFrameRate;
   391     }
   314     }
   392 
   315 
       
   316     CX_DEBUG(("Video resolution (%d,%d)", mCurrentVideoDetails.mWidth,
       
   317                                            mCurrentVideoDetails.mHeight));
       
   318     CX_DEBUG(("Video bitrate = %d)", mCurrentVideoDetails.mVideoBitRate));
   393     CX_DEBUG(("Video frame rate = %d)", frameRate));
   319     CX_DEBUG(("Video frame rate = %d)", frameRate));
   394 
   320 
   395     TRAPD(err,
   321     try {
   396               {
   322         mVideoRecorder->setVideoFrameSize(frameSize);
   397               mVideoRecorder->SetVideoFrameSizeL(frameSize);
   323         mVideoRecorder->setVideoFrameRate(frameRate);
   398               mVideoRecorder->SetVideoFrameRateL(frameRate);
   324         mVideoRecorder->setVideoBitRate(mCurrentVideoDetails.mVideoBitRate);
   399               mVideoRecorder->SetVideoBitRateL(mCurrentVideoDetails.mVideoBitRate);
   325         mVideoRecorder->setAudioEnabled(muteSetting == 0);
   400               mVideoRecorder->SetAudioEnabledL(muteSetting == 0);
   326         // "No limit" value is handled in video recorder wrapper.
   401               // "No limit" value is handled in video recorder wrapper.
   327         mVideoRecorder->setVideoMaxSize(mCurrentVideoDetails.mMaximumSizeInBytes);
   402               mVideoRecorder->SetMaxClipSizeL(mCurrentVideoDetails.mMaximumSizeInBytes);
   328 
   403               }
   329         // Settings have been applied successfully, start to prepare.
   404          );
   330         mVideoRecorder->prepare();
   405 
   331 
   406     if (!err) {
   332         // Prepare snapshot. Snapshot control throws error if problems.
   407         // settings have been applied successfully, start to prepare
   333         QSize snapshotSize = mSnapshotControl.calculateSnapshotSize(
   408         mVideoRecorder->Prepare();
   334                                 mViewfinderControl.deviceDisplayResolution(),
   409         // prepare snapshot
   335                                 mCurrentVideoDetails.mAspectRatio);
   410         err = prepareVideoSnapshot();
   336         mSnapshotControl.start(snapshotSize);
   411     }
   337 
   412 
   338         // Prepare zoom only when there are no errors during prepare.
   413     if (!err) {
       
   414         // prepare zoom only when there are no errors during prepare.
       
   415         emit prepareZoomForVideo();
   339         emit prepareZoomForVideo();
   416     }
   340         emit videoPrepareComplete(CxeError::None);
   417     // emit video prepare status
   341     } catch (const std::exception &e) {
   418     emit videoPrepareComplete(CxeErrorHandlingSymbian::map(err));
   342         // Handle error.
   419 
   343         handlePrepareFailed();
   420     OstTrace0(camerax_performance, DUP1_CXEVIDEOCAPTURECONTROLSYMBIAN_PREPARE, "msg: e_CX_VIDCAPCONT_PREPARE 0");
   344     }
   421 
   345 
   422     CX_DEBUG_EXIT_FUNCTION();
   346     OstTrace0(camerax_performance, CXEVIDEOCAPTURECONTROL_PREPARE_2, "msg: e_CX_VIDCAPCONT_PREPARE 0");
   423 }
   347     CX_DEBUG_EXIT_FUNCTION();
   424 
   348 }
   425 
   349 
   426 
   350 /*!
   427 /*!
   351 * Fetches video qualites details based on video quality setting.
   428 Fetches video qualites details based on video quality setting.
   352 */
   429 Returns CxeError codes if any.
   353 void
   430 */
       
   431 CxeError::Id
       
   432 CxeVideoCaptureControlSymbian::getVideoQualityDetails(CxeVideoDetails &videoInfo)
   354 CxeVideoCaptureControlSymbian::getVideoQualityDetails(CxeVideoDetails &videoInfo)
   433 {
   355 {
   434     CX_DEBUG_ENTER_FUNCTION();
   356     CX_DEBUG_ENTER_FUNCTION();
   435 
   357     OstTrace0( camerax_performance, CXEVIDEOCAPTURECONTROL_GETQUALITYDETAILS_1, "msg: e_CX_GET_QUALITY_DETAILS 1" );
   436     int videoQuality = 0;
   358 
   437     CxeError::Id err = CxeError::None;
   359     int quality(0);
   438 
   360 
       
   361     // Get quality index for primary camera. Only one quality for secondary camera.
   439     if (mCameraDeviceControl.cameraIndex() == Cxe::PrimaryCameraIndex) {
   362     if (mCameraDeviceControl.cameraIndex() == Cxe::PrimaryCameraIndex) {
   440         err = mSettings.get(CxeSettingIds::VIDEO_QUALITY, videoQuality);
   363         CxeException::throwIfError(mSettings.get(CxeSettingIds::VIDEO_QUALITY, quality));
   441 
   364     }
   442         bool validQuality = (videoQuality >= 0 &&
   365 
   443                              videoQuality < mIcmSupportedVideoResolutions.count());
   366     if (quality < 0 || quality >= mIcmSupportedVideoResolutions.count()) {
   444         if (err == CxeError::None && validQuality) {
   367        throw new CxeException(CxeError::NotFound);
   445             // get video quality details
   368     }
   446             videoInfo = mIcmSupportedVideoResolutions.at(videoQuality);
   369 
   447         } else {
   370     // get video quality details
   448             // not valid video quality
   371     videoInfo = mIcmSupportedVideoResolutions.at(quality);
   449             err = CxeError::NotFound;
   372 
   450         }
   373     OstTrace0( camerax_performance, CXEVIDEOCAPTURECONTROL_GETQUALITYDETAILS_2, "msg: e_CX_GET_QUALITY_DETAILS 0" );
   451     } else {
   374     CX_DEBUG_EXIT_FUNCTION();
   452         // get secondary camera video quality index
   375 }
   453         if (mIcmSupportedVideoResolutions.count() > 0) {
       
   454             videoInfo = mIcmSupportedVideoResolutions.at(videoQuality);
       
   455         } else {
       
   456             // not valid video quality
       
   457             err = CxeError::NotFound;
       
   458         }
       
   459     }
       
   460 
       
   461     CX_DEBUG_EXIT_FUNCTION();
       
   462 
       
   463     return err;
       
   464 }
       
   465 
       
   466 
       
   467 /**!
       
   468  Prepare snapshot
       
   469  Returns symbian error code.
       
   470  */
       
   471 int CxeVideoCaptureControlSymbian::prepareVideoSnapshot()
       
   472 {
       
   473     CX_DEBUG_ENTER_FUNCTION();
       
   474 
       
   475     CCamera::CCameraSnapshot *cameraSnapshot = mCameraDevice.cameraSnapshot();
       
   476     CX_ASSERT_ALWAYS(cameraSnapshot);
       
   477 
       
   478     int err = KErrNone;
       
   479     // Whether or not we have postcapture on, we need the snapshot for Thumbnail Manager.
       
   480     if (cameraSnapshot) {
       
   481         // Cancel active snapshot
       
   482         cameraSnapshot->StopSnapshot();
       
   483 
       
   484         // Prepare snapshot
       
   485         CCamera::TFormat snapFormat = CCamera::EFormatFbsBitmapColor16MU;
       
   486         TRAP(err, cameraSnapshot->PrepareSnapshotL(snapFormat,
       
   487                                                    getSnapshotSize(),
       
   488                                                    KMaintainAspectRatio));
       
   489         CX_DEBUG(("PrepareSnapshotL done, err=%d", err));
       
   490         // Start snapshot if no errors encountered.
       
   491         if (err == KErrNone) {
       
   492             CX_DEBUG(("Start video snapshot"));
       
   493             cameraSnapshot->StartSnapshot();
       
   494         }
       
   495     } else {
       
   496         // No snapshot interface available. Report error.
       
   497         // Assert above takes care of this, but keeping this as an option.
       
   498         err = KErrNotReady;
       
   499     }
       
   500 
       
   501     CX_DEBUG_EXIT_FUNCTION();
       
   502 
       
   503     return err;
       
   504 }
       
   505 
       
   506 
       
   507 
       
   508 /*!
       
   509 * Returns snapshot size. Snapshot size is calculated based on the
       
   510 * display resolution and current video aspect ratio.
       
   511 */
       
   512 TSize CxeVideoCaptureControlSymbian::getSnapshotSize() const
       
   513 {
       
   514     CX_DEBUG_ENTER_FUNCTION();
       
   515 
       
   516     TSize snapshotSize;
       
   517 
       
   518     QSize deviceResolution = mViewfinderControl.deviceDisplayResolution();
       
   519     QSize size = QSize(mCurrentVideoDetails.mWidth, mCurrentVideoDetails.mHeight);
       
   520 
       
   521     // scale according to aspect ratio.
       
   522     size.scale(deviceResolution.width(),
       
   523                deviceResolution.height(),
       
   524                Qt::KeepAspectRatio);
       
   525     CX_DEBUG(("Video Snapshot size, (%d,%d)", size.width(), size.height()));
       
   526     snapshotSize.SetSize(size.width(), deviceResolution.height());
       
   527 
       
   528     CX_DEBUG_EXIT_FUNCTION();
       
   529 
       
   530     return snapshotSize;
       
   531 }
       
   532 
       
   533 
       
   534 
       
   535 /**!
       
   536 * Camera events coming from ecam.
       
   537 */
       
   538 void CxeVideoCaptureControlSymbian::handleCameraEvent(int eventUid, int error)
       
   539 {
       
   540     CX_DEBUG_ENTER_FUNCTION();
       
   541     if (eventUid == KUidECamEventSnapshotUidValue) {
       
   542         handleSnapshotEvent(CxeErrorHandlingSymbian::map(error));
       
   543     }
       
   544     CX_DEBUG_EXIT_FUNCTION();
       
   545 }
       
   546 
       
   547 
       
   548 /*!
       
   549 * Handle Snapshot event from ecam
       
   550 */
       
   551 void CxeVideoCaptureControlSymbian::handleSnapshotEvent(CxeError::Id error)
       
   552 {
       
   553     CX_DEBUG_ENTER_FUNCTION();
       
   554 
       
   555     if (state() == Idle) {
       
   556         // we ignore this event, when we are not in active state(s)
       
   557         CX_DEBUG(( "wrong state, ignoring snapshot" ));
       
   558         CX_DEBUG_EXIT_FUNCTION();
       
   559         return;
       
   560     }
       
   561 
       
   562     if (error) {
       
   563         mSnapshot = QPixmap();
       
   564         emit snapshotReady(error, mSnapshot, filename());
       
   565         return;
       
   566     }
       
   567 
       
   568     RArray<TInt> snapList;
       
   569     MCameraBuffer* buffer(NULL);
       
   570     // Note: Cleanup not required in this function
       
   571     CFbsBitmap *snapshot = NULL;
       
   572     TRAPD(snapErr,
       
   573           buffer = &mCameraDevice.cameraSnapshot()->SnapshotDataL(snapList));
       
   574     if (!snapErr) {
       
   575         TInt firstImageIndex = snapList.Find(0);
       
   576         snapList.Close();
       
   577         TRAP(snapErr, snapshot = &(buffer->BitmapL(firstImageIndex)));
       
   578     }
       
   579     if (!snapErr) {
       
   580         TSize size = snapshot->SizeInPixels();
       
   581         TInt sizeInWords = size.iHeight * CFbsBitmap::ScanLineLength(size.iWidth, EColor16MU)
       
   582                 / sizeof(TUint32);
       
   583 
       
   584         TUint32 *snapshotData = NULL;
       
   585         snapshotData = new TUint32[sizeInWords];
       
   586 
       
   587         if (snapshotData) {
       
   588             // Convert to QImage
       
   589             snapshot->LockHeap();
       
   590             TUint32* dataPtr = snapshot->DataAddress();
       
   591             memcpy(snapshotData, dataPtr, sizeof(TUint32) * sizeInWords);
       
   592             snapshot->UnlockHeap();
       
   593 
       
   594 
       
   595             QImage *img = new QImage((uchar*) snapshotData, size.iWidth, size.iHeight,
       
   596                                    CFbsBitmap::ScanLineLength(size.iWidth, EColor16MU),
       
   597                                    QImage::Format_RGB32);
       
   598 
       
   599             mSnapshot = QPixmap::fromImage(*img);
       
   600             delete [] snapshotData;
       
   601             delete img;
       
   602         }
       
   603     }
       
   604     if (buffer) {
       
   605         buffer->Release();
       
   606     }
       
   607     // Snapshot ready
       
   608     emit snapshotReady(CxeErrorHandlingSymbian::map(snapErr), mSnapshot, filename());
       
   609 
       
   610     CX_DEBUG_EXIT_FUNCTION();
       
   611 }
       
   612 
       
   613 
   376 
   614 /*!
   377 /*!
   615 * Resets the video snapshot and current video filename
   378 * Resets the video snapshot and current video filename
   616 */
   379 */
   617 void CxeVideoCaptureControlSymbian::reset()
   380 void CxeVideoCaptureControlSymbian::reset()
   625     mCurrentFilename = QString("");
   388     mCurrentFilename = QString("");
   626 
   389 
   627     CX_DEBUG_EXIT_FUNCTION();
   390     CX_DEBUG_EXIT_FUNCTION();
   628 }
   391 }
   629 
   392 
   630 
       
   631 /*!
   393 /*!
   632 * Returns current video filename
   394 * Returns current video filename
   633 */
   395 */
   634 QString CxeVideoCaptureControlSymbian::filename() const
   396 QString CxeVideoCaptureControlSymbian::filename() const
   635 {
   397 {
   637     // If video recording was started then it returns proper filename
   399     // If video recording was started then it returns proper filename
   638     // otherwise an empty string is returned.
   400     // otherwise an empty string is returned.
   639     return mCurrentFilename;
   401     return mCurrentFilename;
   640 }
   402 }
   641 
   403 
   642 
       
   643 /*!
   404 /*!
   644 * Returns current video snapshot
   405 * Returns current video snapshot
   645 */
   406 */
   646 QPixmap CxeVideoCaptureControlSymbian::snapshot() const
   407 QPixmap CxeVideoCaptureControlSymbian::snapshot() const
   647 {
   408 {
   648     return mSnapshot;
   409     return mSnapshot;
   649 }
   410 }
   650 
       
   651 
   411 
   652 /*!
   412 /*!
   653 * Starts video recording if we are in appropriate state.
   413 * Starts video recording if we are in appropriate state.
   654 */
   414 */
   655 void CxeVideoCaptureControlSymbian::record()
   415 void CxeVideoCaptureControlSymbian::record()
   664     }
   424     }
   665 
   425 
   666     CX_DEBUG_EXIT_FUNCTION();
   426     CX_DEBUG_EXIT_FUNCTION();
   667 }
   427 }
   668 
   428 
   669 
       
   670 /*!
   429 /*!
   671 * Pauses video recording.
   430 * Pauses video recording.
   672 */
   431 */
   673 void CxeVideoCaptureControlSymbian::pause()
   432 void CxeVideoCaptureControlSymbian::pause()
   674 {
   433 {
   675     CX_DEBUG_ENTER_FUNCTION();
   434     CX_DEBUG_ENTER_FUNCTION();
   676 
   435     try {
   677     setState(CxeVideoCaptureControl::Paused);
   436         mVideoRecorder->pause();
   678     TRAPD(pauseErr, mVideoRecorder->PauseL());
   437         setState(CxeVideoCaptureControl::Paused);
   679     // play the sound, but not changing the state
   438         // play the sound, but not changing the state
   680     mVideoStopSoundPlayer->play();
   439         mVideoStopSoundPlayer->play();
   681     if (pauseErr) {
   440     } catch (const std::exception &e) {
   682         CX_DEBUG(("[WARNING] Error %d pausing!", pauseErr));
   441         handleComposeFailed(qt_symbian_exception2Error(e));
   683         //pause operation failed, report it
   442     }
   684         emit videoComposed(CxeErrorHandlingSymbian::map(pauseErr), filename());
   443     CX_DEBUG_EXIT_FUNCTION();
   685         // release resources.
   444 }
   686         deinit();
       
   687     }
       
   688 
       
   689     CX_DEBUG_EXIT_FUNCTION();
       
   690 }
       
   691 
       
   692 
   445 
   693 /*!
   446 /*!
   694 * Stops video recording.
   447 * Stops video recording.
   695 */
   448 */
   696 void CxeVideoCaptureControlSymbian::stop()
   449 void CxeVideoCaptureControlSymbian::stop()
   699 
   452 
   700     if (state() == Recording || state() == Paused) {
   453     if (state() == Recording || state() == Paused) {
   701         // first stop viewfinder
   454         // first stop viewfinder
   702         mViewfinderControl.stop();
   455         mViewfinderControl.stop();
   703 
   456 
   704         TInt asyncStopErr = mVideoRecorder->CustomCommandSync(
   457         try {
   705             TMMFMessageDestination(KCamCControllerImplementationUid,
   458             // Try asynchronous stopping first.
   706                                    KMMFObjectHandleController),
   459             mVideoRecorder->stop(true);
   707             ECamCControllerCCVideoStopAsync,
   460             // No error from asynchronous stop -> wait for stop event
   708             KNullDesC8,
   461             setState(Stopping);
   709             KNullDesC8 );
   462         } catch (const std::exception &e) {
   710         CX_DEBUG(("ECamCControllerCCVideoStopAsync sent, err=%d", asyncStopErr));
   463             CX_DEBUG(("CxeVideoCaptureControlSymbian - async stop failed, try sync.."));
   711         if (asyncStopErr) { // fall back to synchronous stop
   464             try {
   712             TInt syncStopErr = mVideoRecorder->Stop();
   465                 mVideoRecorder->stop(false);
   713             if (syncStopErr) {
   466                 // stopping went ok
   714                 // error during stop operation, release resources
   467                 emulateNormalStopping();
   715                 emit videoComposed(CxeErrorHandlingSymbian::map(asyncStopErr), filename());
   468             } catch (const std::exception &e) {
   716                 deinit();
   469                 // Even synchronous stopping failed -> release resources.
   717             } else {
   470                 CX_DEBUG(("CxeVideoCaptureControlSymbian - sync stop failed, too!"));
   718                 // stop operation went fine, set back the state to Initialized.
   471                 handleComposeFailed(qt_symbian_exception2Error(e));
   719                 setState(Initialized);
       
   720                 mFilenameGenerator.raiseCounterValue();
       
   721             }
   472             }
       
   473         }
       
   474     }
       
   475 
       
   476     CX_DEBUG_EXIT_FUNCTION();
       
   477 }
       
   478 
       
   479 /*!
       
   480 * Callback when "Open" operation is complete.
       
   481 */
       
   482 void CxeVideoCaptureControlSymbian::MvruoOpenComplete(TInt aError)
       
   483 {
       
   484     CX_DEBUG_ENTER_FUNCTION();
       
   485     CX_DEBUG(("CxeVideoCaptureControlSymbian::MvruoOpenComplete, err=%d", aError));
       
   486 
       
   487     if (state() == Preparing) {
       
   488         if (!aError) {
       
   489             prepare();
   722         } else {
   490         } else {
   723             // No error from asynch stop custom command... wait for stop event
   491             handlePrepareFailed();
   724             setState(Stopping);
   492         }
   725             mFilenameGenerator.raiseCounterValue();
   493     }
   726         }
   494 
   727     }
   495     CX_DEBUG_EXIT_FUNCTION();
   728 
   496 }
   729     CX_DEBUG_EXIT_FUNCTION();
       
   730 }
       
   731 
       
   732 
       
   733 /*!
       
   734 * Callback when "Open" operation is complete.
       
   735 */
       
   736 void CxeVideoCaptureControlSymbian::MvruoOpenComplete(TInt aError)
       
   737 {
       
   738     CX_DEBUG_ENTER_FUNCTION();
       
   739     CX_DEBUG(("CxeVideoCaptureControlSymbian::MvruoOpenComplete, err=%d", aError));
       
   740 
       
   741     if (state() == Preparing) {
       
   742         if (aError != KErrNone) {
       
   743             deinit();
       
   744             CxeError::Id err = CxeErrorHandlingSymbian::map(KErrNotReady);
       
   745             // report error to interested parties
       
   746             emit videoPrepareComplete(CxeErrorHandlingSymbian::map(err));
       
   747         } else {
       
   748             prepare();
       
   749         }
       
   750     }
       
   751 
       
   752     CX_DEBUG_EXIT_FUNCTION();
       
   753 }
       
   754 
       
   755 
   497 
   756 /*!
   498 /*!
   757 * Callback when "Prepare" request is complete.
   499 * Callback when "Prepare" request is complete.
   758 */
   500 */
   759 void CxeVideoCaptureControlSymbian::MvruoPrepareComplete(TInt aError)
   501 void CxeVideoCaptureControlSymbian::MvruoPrepareComplete(TInt aError)
   765         if (!aError) {
   507         if (!aError) {
   766             setState(CxeVideoCaptureControl::Ready);
   508             setState(CxeVideoCaptureControl::Ready);
   767             mViewfinderControl.start();
   509             mViewfinderControl.start();
   768             OstTrace0( camerax_performance, CXEVIDEOCAPTURECONTROLSYMBIAN_GOTOVIDEO, "msg: e_CX_GO_TO_VIDEO_MODE 0" );
   510             OstTrace0( camerax_performance, CXEVIDEOCAPTURECONTROLSYMBIAN_GOTOVIDEO, "msg: e_CX_GO_TO_VIDEO_MODE 0" );
   769         } else {
   511         } else {
   770             deinit();
   512             handlePrepareFailed();
   771             // report error to interested parties
   513         }
   772             CxeError::Id err = CxeErrorHandlingSymbian::map(KErrNotReady);
   514     }
   773             emit videoPrepareComplete(CxeErrorHandlingSymbian::map(err));
   515 
   774         }
   516     CX_DEBUG_EXIT_FUNCTION();
   775     }
   517 }
   776 
       
   777     CX_DEBUG_EXIT_FUNCTION();
       
   778 }
       
   779 
       
   780 
   518 
   781 /*!
   519 /*!
   782 * Callback when "Record" operation is complete.
   520 * Callback when "Record" operation is complete.
   783 */
   521 */
   784 void CxeVideoCaptureControlSymbian::MvruoRecordComplete(TInt aError)
   522 void CxeVideoCaptureControlSymbian::MvruoRecordComplete(TInt aError)
   791         setState(CxeVideoCaptureControl::Ready);
   529         setState(CxeVideoCaptureControl::Ready);
   792     } else if (aError == KErrCompletion) {
   530     } else if (aError == KErrCompletion) {
   793         // KErrCompletion is received when video recording stops
   531         // KErrCompletion is received when video recording stops
   794         // because of maximum clip size is reached. Emulate
   532         // because of maximum clip size is reached. Emulate
   795         // normal stopping.
   533         // normal stopping.
   796         setState(Stopping);
   534         emulateNormalStopping();
   797         MvruoEvent(TMMFEvent(KCamCControllerCCVideoRecordStopped, KErrNone));
       
   798         MvruoEvent(TMMFEvent(KCamCControllerCCVideoFileComposed, KErrNone));
       
   799     }
   535     }
   800     else {
   536     else {
   801         // error during recording, report to client
   537         // error during recording, report to client
   802         deinit();
   538         handleComposeFailed(aError);
   803         emit videoComposed(CxeErrorHandlingSymbian::map(aError), filename());
   539     }
   804     }
   540 
   805 
   541     CX_DEBUG_EXIT_FUNCTION();
   806     CX_DEBUG_EXIT_FUNCTION();
   542 }
   807 }
       
   808 
       
   809 
   543 
   810 /*!
   544 /*!
   811 * Callback from MVideoRecorderUtilityObserver
   545 * Callback from MVideoRecorderUtilityObserver
   812 */
   546 */
   813 void CxeVideoCaptureControlSymbian::MvruoEvent(const TMMFEvent& aEvent)
   547 void CxeVideoCaptureControlSymbian::MvruoEvent(const TMMFEvent& aEvent)
   822         CX_DEBUG(("KCamCControllerCCVideoFileComposed"));
   556         CX_DEBUG(("KCamCControllerCCVideoFileComposed"));
   823         if (state() == Stopping) {
   557         if (state() == Stopping) {
   824             // stop operation went fine, set back the state to intialized.
   558             // stop operation went fine, set back the state to intialized.
   825             setState(Initialized);
   559             setState(Initialized);
   826         }
   560         }
       
   561         mFilenameGenerator.raiseCounterValue();
   827         // video file has composed, everything went well, inform the client
   562         // video file has composed, everything went well, inform the client
   828         emit videoComposed(CxeError::None, filename());
   563         emit videoComposed(CxeError::None, filename());
   829         // revert back the new filename to empty string, since recording
       
   830         // is complete and we need to generate a new file name
       
   831         mNewFileName = QString("");
       
   832     } else {
   564     } else {
   833         CX_DEBUG(("ignoring unknown MvruoEvent 0x%08x", aEvent.iEventType.iUid ));
   565         CX_DEBUG(("ignoring unknown MvruoEvent 0x%08x", aEvent.iEventType.iUid ));
   834     }
   566     }
   835 
   567 
   836     CX_DEBUG_EXIT_FUNCTION();
   568     CX_DEBUG_EXIT_FUNCTION();
   837 }
   569 }
   838 
   570 
   839 
       
   840 /*!
       
   841 Get corresponding controller for video capture.
       
   842 @param aMimeType denotes videofile mimetype,
       
   843 @param aPreferredSupplier denotes supplier.
       
   844 Returns CxeError::Id if any.
       
   845 */
       
   846 CxeError::Id
       
   847 CxeVideoCaptureControlSymbian::findVideoController(const TDesC8& aMimeType,
       
   848                                                    const TDesC& aSupplier)
       
   849 {
       
   850     CX_DEBUG_ENTER_FUNCTION();
       
   851 
       
   852     CX_DEBUG(("video file mime type : %s", &aMimeType));
       
   853     CX_DEBUG(("supplier name: %s", &aSupplier));
       
   854 
       
   855     mVideoControllerUid.iUid = 0;
       
   856     mVideoFormatUid.iUid = 0;
       
   857 
       
   858     // Retrieve a list of possible controllers from ECOM.
       
   859     // Controller must support recording the requested mime type.
       
   860     // Controller must be provided by preferred supplier.
       
   861 
       
   862     CMMFControllerPluginSelectionParameters* cSelect(NULL);
       
   863     CMMFFormatSelectionParameters* fSelect(NULL);
       
   864     RMMFControllerImplInfoArray controllers;
       
   865 
       
   866     TRAPD(err, cSelect = CMMFControllerPluginSelectionParameters::NewL());
       
   867     if (err) {
       
   868         return CxeErrorHandlingSymbian::map(err);
       
   869     }
       
   870 
       
   871     TRAP(err, fSelect = CMMFFormatSelectionParameters::NewL());
       
   872     if (err) {
       
   873         if(cSelect) {
       
   874             delete cSelect;
       
   875         }
       
   876         return CxeErrorHandlingSymbian::map(err);
       
   877     }
       
   878 
       
   879     TRAP( err, {
       
   880         fSelect->SetMatchToMimeTypeL(aMimeType);
       
   881         cSelect->SetRequiredRecordFormatSupportL(*fSelect);
       
   882         cSelect->SetPreferredSupplierL(aSupplier,
       
   883                                        CMMFPluginSelectionParameters::EOnlyPreferredSupplierPluginsReturned);
       
   884         cSelect->ListImplementationsL(controllers);
       
   885     } );
       
   886 
       
   887     if (!err && controllers.Count() >= 1) {
       
   888         // KErrNotFound is returned unless a controller is found
       
   889         err = KErrNotFound;
       
   890         // Get the controller UID.
       
   891         mVideoControllerUid = controllers[0]->Uid();
       
   892 
       
   893         // Inquires the controller about supported formats.
       
   894         // We use the first controller found having index 0.
       
   895         RMMFFormatImplInfoArray formats;
       
   896         formats = controllers[0]->RecordFormats();
       
   897 
       
   898         // Get the first format that supports our mime type.
       
   899         int count = formats.Count();
       
   900         for (int i=0; i<count; i++) {
       
   901             if (formats[i]->SupportsMimeType(aMimeType)) {
       
   902                 mVideoFormatUid = formats[i]->Uid(); // set the UID
       
   903                 err = KErrNone;
       
   904                 break;
       
   905             }
       
   906         }
       
   907     }
       
   908     delete cSelect;
       
   909     delete fSelect;
       
   910     controllers.ResetAndDestroy();
       
   911 
       
   912     CX_DEBUG_EXIT_FUNCTION();
       
   913 
       
   914     return CxeErrorHandlingSymbian::map(err);
       
   915 }
       
   916 
       
   917 
       
   918 /*!
   571 /*!
   919 * camera reference changing, release resources
   572 * camera reference changing, release resources
   920 */
   573 */
   921 void CxeVideoCaptureControlSymbian::prepareForCameraDelete()
   574 void CxeVideoCaptureControlSymbian::prepareForCameraDelete()
   922 {
   575 {
   933     CX_DEBUG_ENTER_FUNCTION();
   586     CX_DEBUG_ENTER_FUNCTION();
   934     deinit();
   587     deinit();
   935     CX_DEBUG_EXIT_FUNCTION();
   588     CX_DEBUG_EXIT_FUNCTION();
   936 }
   589 }
   937 
   590 
   938 
   591 /*!
   939 /*!
   592 * new camera available
   940 * new camera available,
       
   941 */
   593 */
   942 void CxeVideoCaptureControlSymbian::handleCameraAllocated(CxeError::Id error)
   594 void CxeVideoCaptureControlSymbian::handleCameraAllocated(CxeError::Id error)
   943 {
   595 {
   944     CX_DEBUG_ENTER_FUNCTION();
   596     CX_DEBUG_ENTER_FUNCTION();
   945 
   597 
   946     if (!error) {
   598     if (!error) {
   947         // initialize the video recorder utility
   599         try {
   948         createVideoRecorder();
   600             // Create the video recorder utility
       
   601             createVideoRecorder();
       
   602         } catch (...) {
       
   603             // We are just trying to create the recorder early.
       
   604             // Retry later when preparing, and fail then if
       
   605             // error still persists.
       
   606         }
   949         // new camera available, read supported video qualities from icm
   607         // new camera available, read supported video qualities from icm
   950         // load all still qualities supported by icm
   608         // load all video qualities supported by icm
   951         mIcmSupportedVideoResolutions.clear();
   609         mIcmSupportedVideoResolutions.clear();
   952         Cxe::CameraIndex cameraIndex = mCameraDeviceControl.cameraIndex();
   610         Cxe::CameraIndex cameraIndex = mCameraDeviceControl.cameraIndex();
   953         // get list of supported image qualities based on camera index
   611         // get list of supported image qualities based on camera index
   954         mIcmSupportedVideoResolutions =
   612         mIcmSupportedVideoResolutions =
   955                 mQualityPresets.videoQualityPresets(cameraIndex);
   613                 mQualityPresets.videoQualityPresets(cameraIndex);
   956     }
   614     }
   957 
   615 
   958     CX_DEBUG_EXIT_FUNCTION();
   616     CX_DEBUG_EXIT_FUNCTION();
   959 }
   617 }
   960 
   618 
   961 
       
   962 /*!
   619 /*!
   963 * Initializes video recorder.
   620 * Initializes video recorder.
       
   621 * May throw exception.
   964 */
   622 */
   965 void CxeVideoCaptureControlSymbian::createVideoRecorder()
   623 void CxeVideoCaptureControlSymbian::createVideoRecorder()
   966 {
   624 {
   967     CX_DEBUG_ENTER_FUNCTION();
   625     CX_DEBUG_ENTER_FUNCTION();
   968 
   626     if (mVideoRecorder == NULL) {
   969     // init video recoder
   627         mVideoRecorder = new CxeVideoRecorderUtilitySymbian(*this);
   970     if (state() == CxeVideoCaptureControl::Idle) {
   628     }
   971         if (mVideoRecorder == NULL) {
   629     CX_DEBUG_EXIT_FUNCTION();
   972             TRAPD(initErr, mVideoRecorder =
   630 }
   973                 new CxeVideoRecorderUtilitySymbian( *this ,
   631 
   974                             KAudioPriorityVideoRecording,
   632 /*!
   975                             TMdaPriorityPreference( KAudioPrefVideoRecording )));
   633 * releases resources used by video capture control
   976             if (initErr) {
       
   977                 CX_DEBUG(("WARNING - VideoRecorderUtility could not be reserved. Failed with err:%d", initErr));
       
   978                 mVideoRecorder = NULL;
       
   979             }
       
   980         }
       
   981     }
       
   982 
       
   983     CX_DEBUG_EXIT_FUNCTION();
       
   984 }
       
   985 
       
   986 
       
   987 /*!
       
   988 * releases resources used by videocapture
       
   989 */
   634 */
   990 void CxeVideoCaptureControlSymbian::releaseResources()
   635 void CxeVideoCaptureControlSymbian::releaseResources()
   991 {
   636 {
   992     CX_DEBUG_ENTER_FUNCTION();
   637     CX_DEBUG_ENTER_FUNCTION();
   993 
       
   994     // Save the state and filename before releasing.
       
   995     QString filenameCopy(filename());
       
   996     CxeVideoCaptureControl::State stateCopy(state());
       
   997 
   638 
   998     // first de-init videocapture control
   639     // first de-init videocapture control
   999     deinit();
   640     deinit();
  1000     reset();
   641     reset();
  1001 
   642 
  1002     // Check if state is stopping, in which case we have to inform the
       
  1003     // file harvester that a file is to be completed. We would not
       
  1004     // call harvestFile otherwise in this case.
       
  1005     // Otherwise the video will not be found from videos app.
       
  1006     if (stateCopy == CxeVideoCaptureControl::Stopping) {
       
  1007         emit videoComposed(CxeError::None, filenameCopy);
       
  1008     }
       
  1009 
       
  1010     delete mVideoRecorder;
   643     delete mVideoRecorder;
  1011     mVideoRecorder = NULL;
   644     mVideoRecorder = NULL;
  1012 
   645 
  1013     CX_DEBUG_EXIT_FUNCTION();
   646     CX_DEBUG_EXIT_FUNCTION();
  1014 }
   647 }
  1015 
   648 
  1016 
   649 /*!
  1017 /*!
   650 * Returns current state of video capture control
  1018 Returns current state of videocapture
       
  1019 */
   651 */
  1020 CxeVideoCaptureControl::State CxeVideoCaptureControlSymbian::state() const
   652 CxeVideoCaptureControl::State CxeVideoCaptureControlSymbian::state() const
  1021 {
   653 {
  1022     return static_cast<CxeVideoCaptureControl::State> (stateId());
   654     return static_cast<CxeVideoCaptureControl::State> (stateId());
  1023 }
   655 }
  1024 
   656 
  1025 
   657 /*!
  1026 /*!
   658 * Called when state is changed.
  1027 * slot called when state is changed.
       
  1028 */
   659 */
  1029 void CxeVideoCaptureControlSymbian::handleStateChanged(int newStateId, CxeError::Id error)
   660 void CxeVideoCaptureControlSymbian::handleStateChanged(int newStateId, CxeError::Id error)
  1030 {
   661 {
  1031     switch (newStateId) {
   662     switch (newStateId) {
  1032     case Ready:
   663     case Ready:
  1044         }
   675         }
  1045         break;
   676         break;
  1046     }
   677     }
  1047     emit stateChanged(static_cast<State> (newStateId), error);
   678     emit stateChanged(static_cast<State> (newStateId), error);
  1048 }
   679 }
  1049 
       
  1050 
   680 
  1051 /*!
   681 /*!
  1052 * Initialize states for videocapturecontrol
   682 * Initialize states for videocapturecontrol
  1053 */
   683 */
  1054 void CxeVideoCaptureControlSymbian::initializeStates()
   684 void CxeVideoCaptureControlSymbian::initializeStates()
  1064     addState(new CxeState(PlayingStartSound, "PlayingStartSound", Recording | Idle));
   694     addState(new CxeState(PlayingStartSound, "PlayingStartSound", Recording | Idle));
  1065 
   695 
  1066     setInitialState(Idle);
   696     setInitialState(Idle);
  1067 }
   697 }
  1068 
   698 
  1069 
       
  1070 /*!
   699 /*!
  1071 * Updates remaining video recordng time counter to all the video qualities supported by ICM
   700 * Updates remaining video recordng time counter to all the video qualities supported by ICM
  1072 * this should be done whenever storage location setting changes and when values are
   701 * this should be done whenever storage location setting changes and when values are
  1073 * read from ICM for the first time
   702 * read from ICM for the first time
  1074 */
   703 */
  1076 {
   705 {
  1077     CX_DEBUG_ENTER_FUNCTION();
   706     CX_DEBUG_ENTER_FUNCTION();
  1078 
   707 
  1079     for( int index = 0; index < mIcmSupportedVideoResolutions.count(); index++) {
   708     for( int index = 0; index < mIcmSupportedVideoResolutions.count(); index++) {
  1080         CxeVideoDetails &qualityDetails = mIcmSupportedVideoResolutions[index];
   709         CxeVideoDetails &qualityDetails = mIcmSupportedVideoResolutions[index];
  1081         calculateRemainingTime(qualityDetails, qualityDetails.mRemainingTime);
   710         qualityDetails.mRemainingTime = calculateRemainingTime(qualityDetails);
  1082     }
   711     }
  1083 
   712 
  1084     CX_DEBUG_EXIT_FUNCTION();
   713     CX_DEBUG_EXIT_FUNCTION();
  1085 }
   714 }
  1086 
   715 
  1087 /*
   716 /*!
  1088 * calculates remaining video recording time.
   717 * calculates remaining video recording time.
  1089 */
   718 */
  1090 void CxeVideoCaptureControlSymbian::remainingTime(int &time)
   719 void CxeVideoCaptureControlSymbian::remainingTime(int &time)
  1091 {
   720 {
  1092     CX_DEBUG_ENTER_FUNCTION();
   721     CX_DEBUG_ENTER_FUNCTION();
  1093 
   722 
  1094     if (state() == CxeVideoCaptureControl::Recording ||
   723     if (state() == CxeVideoCaptureControl::Recording ||
  1095         state() == CxeVideoCaptureControl::Paused) {
   724         state() == CxeVideoCaptureControl::Paused) {
  1096         TTimeIntervalMicroSeconds remaining = 0;
   725         time = mVideoRecorder->availableRecordingTime();
  1097         remaining = mVideoRecorder->RecordTimeAvailable();
   726         CX_DEBUG(("CxeVideoCaptureControlSymbian - time remaining: %d", time));
  1098         time = remaining.Int64() * 1.0 / KOneSecond;
       
  1099         CX_DEBUG(( "timeRemaining2: %d", time ));
       
  1100     } else {
   727     } else {
  1101         // Check if we need to recalculate the remaining time.
   728         // Check if we need to recalculate the remaining time.
  1102         if (mCurrentVideoDetails.mRemainingTime == CxeVideoDetails::UNKNOWN) {
   729         if (mCurrentVideoDetails.mRemainingTime == CxeVideoDetails::UNKNOWN) {
  1103             calculateRemainingTime(mCurrentVideoDetails, mCurrentVideoDetails.mRemainingTime);
   730             mCurrentVideoDetails.mRemainingTime = calculateRemainingTime(mCurrentVideoDetails);
  1104         }
   731         }
  1105         time = mCurrentVideoDetails.mRemainingTime;
   732         time = mCurrentVideoDetails.mRemainingTime;
  1106     }
   733     }
  1107 
   734 
  1108     CX_DEBUG_EXIT_FUNCTION();
   735     CX_DEBUG_EXIT_FUNCTION();
  1109 }
   736 }
  1110 
   737 
  1111 
   738 /*!
  1112 
   739 * Get the remaining recording time
  1113 /*!
   740 * @param videoDetails Contains the current video resolution that is in use.
  1114 * algorithm to calculate remaining recording time
   741 * @return The remaining recording time
  1115 @ param videoDetails contains the current video resolution that is in use.
   742 */
  1116 @ time contains the remaining recording time
   743 int CxeVideoCaptureControlSymbian::calculateRemainingTime(const CxeVideoDetails& videoDetails)
  1117 */
   744 {
  1118 void CxeVideoCaptureControlSymbian::calculateRemainingTime(CxeVideoDetails videoDetails, int &time)
   745     CX_DEBUG_ENTER_FUNCTION();
  1119 {
   746     qint64 availableSpace = mDiskMonitor.free() - KMinRequiredSpaceVideo;
  1120     CX_DEBUG_ENTER_FUNCTION();
   747     int time = mQualityPresets.recordingTimeAvailable(videoDetails, availableSpace);
  1121 
   748     CX_DEBUG_EXIT_FUNCTION();
  1122     TTimeIntervalMicroSeconds remaining = 0;
   749     return time;
  1123 
   750 }
  1124     // get available space in the drive selected in the settings
   751 
  1125     // for storing videos
   752 /*!
  1126     qint64 availableSpace = mDiskMonitor.free();
   753 * Calculates elapsed recording time during video recording
  1127 
   754 * @return Did fetching elapsed time succeed.
  1128     availableSpace = availableSpace - KMinRequiredSpaceVideo;
       
  1129 
       
  1130     // Maximum clip size may be limited for mms quality.
       
  1131     // If mMaximumSizeInBytes == 0, no limit is specified.
       
  1132     if (videoDetails.mMaximumSizeInBytes > 0 && videoDetails.mMaximumSizeInBytes < availableSpace) {
       
  1133         availableSpace = videoDetails.mMaximumSizeInBytes;
       
  1134     }
       
  1135 
       
  1136     // Use average audio/video bitrates to estimate remaining time
       
  1137     quint32  averageBitRate = 0;
       
  1138     quint32  averageByteRate = 0;
       
  1139     qreal    scaler = mQualityPresets.avgVideoBitRateScaler();
       
  1140 
       
  1141     if (scaler == 0) {
       
  1142         // video bit rate scaler is 0, use the constant value
       
  1143         scaler = KCMRAvgVideoBitRateScaler;
       
  1144     }
       
  1145 
       
  1146     int avgVideoBitRate = (videoDetails.mVideoBitRate * scaler);
       
  1147     int avgAudioBitRate =  videoDetails.mAudioBitRate;
       
  1148 
       
  1149     int muteSetting = 0; // audio enabled
       
  1150     mSettings.get(CxeSettingIds::VIDEO_MUTE_SETTING, muteSetting);
       
  1151 
       
  1152     if (muteSetting == 1) {
       
  1153         // audio disabled from setting. hence no audio
       
  1154         avgAudioBitRate = 0;
       
  1155     }
       
  1156 
       
  1157     averageBitRate = (quint32)(
       
  1158                      (avgVideoBitRate + avgAudioBitRate) * KMetaDataCoeff);
       
  1159 
       
  1160     averageByteRate = averageBitRate / 8;
       
  1161 
       
  1162     if (availableSpace <= 0) {
       
  1163         remaining = 0;
       
  1164     } else {
       
  1165         // converting microseconds to seconds
       
  1166         remaining = availableSpace * KOneMillion / averageByteRate;
       
  1167         if ( (remaining.Int64()) > (quint64(KCamCMaxClipDurationInSecs) * KOneMillion) ) {
       
  1168             remaining = (quint64(KCamCMaxClipDurationInSecs) * KOneMillion);
       
  1169         }
       
  1170     }
       
  1171     if ( remaining <= quint64(0) ) {
       
  1172         remaining = 0;
       
  1173     }
       
  1174 
       
  1175     time = remaining.Int64() * 1.0 / KOneSecond;
       
  1176 
       
  1177     CX_DEBUG(( "remaining time from algorithm: %d", time ));
       
  1178 
       
  1179     CX_DEBUG_EXIT_FUNCTION();
       
  1180 }
       
  1181 
       
  1182 
       
  1183 /*!
       
  1184 * Calculates remaining recording time during video recording
       
  1185 */
   755 */
  1186 bool CxeVideoCaptureControlSymbian::elapsedTime(int &time)
   756 bool CxeVideoCaptureControlSymbian::elapsedTime(int &time)
  1187 {
   757 {
  1188     CX_DEBUG_ENTER_FUNCTION();
   758     CX_DEBUG_ENTER_FUNCTION();
  1189 
   759 
  1190     TTimeIntervalMicroSeconds timeElapsed = 0;
       
  1191     bool ok = false;
   760     bool ok = false;
  1192     if (state() == CxeVideoCaptureControl::Recording ||
   761     if (state() == CxeVideoCaptureControl::Recording ||
  1193         state() == CxeVideoCaptureControl::Paused) {
   762         state() == CxeVideoCaptureControl::Paused) {
  1194         TRAPD( err, timeElapsed = mVideoRecorder->DurationL() );
   763         try {
  1195         if (!err) {
   764             time = mVideoRecorder->duration();
  1196             time = timeElapsed.Int64() * 1.0 / KOneSecond;
   765             CX_DEBUG(("CxeVideoCaptureControlSymbian - elapsed: %d", time));
  1197             CX_DEBUG(("timeElapsed2: %d", time));
       
  1198             ok = true;
   766             ok = true;
  1199         }
   767         } catch (const std::exception &e) {
  1200     }
   768             // Returning false.
  1201 
   769         }
  1202     CX_DEBUG_EXIT_FUNCTION();
   770     }
  1203 
   771 
       
   772     CX_DEBUG_EXIT_FUNCTION();
  1204     return ok;
   773     return ok;
  1205 }
   774 }
  1206 
   775 
  1207 /*!
   776 /*!
  1208 * slot called when playing a sound has finished.
   777 * slot called when playing a sound has finished.
  1212     CX_DEBUG_ENTER_FUNCTION();
   781     CX_DEBUG_ENTER_FUNCTION();
  1213 
   782 
  1214     // start recording, if we were playing capture sound
   783     // start recording, if we were playing capture sound
  1215     if (state() == CxeVideoCaptureControl::PlayingStartSound) {
   784     if (state() == CxeVideoCaptureControl::PlayingStartSound) {
  1216         setState(CxeVideoCaptureControl::Recording);
   785         setState(CxeVideoCaptureControl::Recording);
  1217 
   786         mVideoRecorder->record();
  1218         mVideoRecorder->Record();
       
  1219     }
   787     }
  1220 
   788 
  1221     // in case of video capture stop sound playing, nothing needs to be done
   789     // in case of video capture stop sound playing, nothing needs to be done
  1222     // meaning the state set elsewhere, and the video capture has been stopped already
   790     // meaning the state set elsewhere, and the video capture has been stopped already
  1223 
   791 
  1224     CX_DEBUG_EXIT_FUNCTION();
   792     CX_DEBUG_EXIT_FUNCTION();
  1225 }
   793 }
  1226 
   794 
       
   795 /*!
       
   796 * Handle new snapshot.
       
   797 * @param status Status code for getting the snapshot.
       
   798 * @param snapshot Snapshot pixmap. Empty if error code reported.
       
   799 */
       
   800 void CxeVideoCaptureControlSymbian::handleSnapshotReady(CxeError::Id status, const QImage &snapshot)
       
   801 {
       
   802     CX_DEBUG_ENTER_FUNCTION();
       
   803 
       
   804     if (mCameraDeviceControl.mode() == Cxe::VideoMode) {
       
   805         OstTrace0(camerax_performance, CXEVIDEOCAPTURECONTROL_HANDLESNAPSHOT_1, "msg: e_CX_HANDLE_SNAPSHOT 1");
       
   806 
       
   807         // Need to store snapshot for ui to be able to get it also later.
       
   808         mSnapshot = QPixmap::fromImage(snapshot);
       
   809         emit snapshotReady(status, snapshot, filename());
       
   810 
       
   811         OstTrace0(camerax_performance, CXEVIDEOCAPTURECONTROL_HANDLESNAPSHOT_2, "msg: e_CX_HANDLE_SNAPSHOT 0");
       
   812     }
       
   813 
       
   814     CX_DEBUG_EXIT_FUNCTION();
       
   815 }
  1227 
   816 
  1228 /*!
   817 /*!
  1229 * setting has changed, check if we are interested.
   818 * setting has changed, check if we are interested.
  1230 */
   819 */
  1231 void CxeVideoCaptureControlSymbian::handleSettingValueChanged(const QString& settingId,
   820 void CxeVideoCaptureControlSymbian::handleSettingValueChanged(const QString& settingId,
  1245             }
   834             }
  1246         } else if (settingId == CxeSettingIds::VIDEO_MUTE_SETTING) {
   835         } else if (settingId == CxeSettingIds::VIDEO_MUTE_SETTING) {
  1247             // mute setting changed, apply the new setting and re-prepare.
   836             // mute setting changed, apply the new setting and re-prepare.
  1248             setState(Preparing);
   837             setState(Preparing);
  1249             prepare();
   838             prepare();
  1250         } else if (settingId == CxeSettingIds::FRAME_RATE){
   839         } else if (settingId == CxeSettingIds::FRAME_RATE) {
  1251             // Frame rate setting changed. Need to re-prepare if we are prepared already.
   840             // Frame rate setting changed. Need to re-prepare if we are prepared already.
  1252             // Otherwise can wait for next init call.
   841             // Otherwise can wait for next init call.
  1253             if (state() == Ready) {
   842             if (state() == Ready) {
  1254                 setState(Preparing);
   843                 setState(Preparing);
  1255                 prepare();
   844                 prepare();
  1266  * Scene mode changed. We need to know about it because frame rate
   855  * Scene mode changed. We need to know about it because frame rate
  1267  * might have changed.
   856  * might have changed.
  1268  */
   857  */
  1269 void CxeVideoCaptureControlSymbian::handleSceneChanged(CxeScene& scene)
   858 void CxeVideoCaptureControlSymbian::handleSceneChanged(CxeScene& scene)
  1270 {
   859 {
       
   860     Q_UNUSED(scene)
  1271     CX_DEBUG_ENTER_FUNCTION();
   861     CX_DEBUG_ENTER_FUNCTION();
  1272 
   862 
  1273     // make sure we are in video mode
   863     // make sure we are in video mode
  1274     if (mCameraDeviceControl.mode() == Cxe::VideoMode) {
   864     if (mCameraDeviceControl.mode() == Cxe::VideoMode) {
  1275         // Frame rate setting might have changed so re-prepare.
   865         // Frame rate setting might have changed so re-prepare.
  1291     CX_DEBUG_ENTER_FUNCTION();
   881     CX_DEBUG_ENTER_FUNCTION();
  1292 
   882 
  1293     // Ignore updates on preparing phase.
   883     // Ignore updates on preparing phase.
  1294     if (state() == CxeVideoCaptureControl::Ready) {
   884     if (state() == CxeVideoCaptureControl::Ready) {
  1295 
   885 
  1296         int time(0);
   886         int time(calculateRemainingTime(mCurrentVideoDetails));
  1297         calculateRemainingTime(mCurrentVideoDetails, time);
       
  1298 
   887 
  1299         if (time !=  mCurrentVideoDetails.mRemainingTime) {
   888         if (time !=  mCurrentVideoDetails.mRemainingTime) {
  1300             mCurrentVideoDetails.mRemainingTime = time;
   889             mCurrentVideoDetails.mRemainingTime = time;
  1301             emit remainingTimeChanged();
   890             emit remainingTimeChanged();
  1302         }
   891         }
  1314     // update the remaining time counters for each quality setting
   903     // update the remaining time counters for each quality setting
  1315     updateRemainingRecordingTimeCounter();
   904     updateRemainingRecordingTimeCounter();
  1316     return mIcmSupportedVideoResolutions;
   905     return mIcmSupportedVideoResolutions;
  1317 }
   906 }
  1318 
   907 
       
   908 /*!
       
   909 * Helper method to handle error during preparing phase.
       
   910 */
       
   911 void CxeVideoCaptureControlSymbian::handlePrepareFailed()
       
   912 {
       
   913     CX_DEBUG_ENTER_FUNCTION();
       
   914     CX_DEBUG(("[ERROR] Preparing video failed!"));
       
   915     // Cleanup
       
   916     deinit();
       
   917     // Inform client
       
   918     emit videoPrepareComplete(CxeError::InitializationFailed);
       
   919     CX_DEBUG_EXIT_FUNCTION();
       
   920 }
       
   921 
       
   922 /*!
       
   923 * Helper method to handle error from video composing.
       
   924 * @param error Symbian error code.
       
   925 */
       
   926 void CxeVideoCaptureControlSymbian::handleComposeFailed(int error)
       
   927 {
       
   928     CX_DEBUG_ENTER_FUNCTION();
       
   929     CX_DEBUG(("[ERROR] Composing video failed!"));
       
   930     // Inform client
       
   931     emit videoComposed(CxeErrorHandlingSymbian::map(error), filename());
       
   932     // Cleanup
       
   933     deinit();
       
   934     CX_DEBUG_EXIT_FUNCTION();
       
   935 }
       
   936 
       
   937 /*!
       
   938  * Helper method to emulate video stopping events.
       
   939  */
       
   940 void CxeVideoCaptureControlSymbian::emulateNormalStopping()
       
   941 {
       
   942     CX_DEBUG_ENTER_FUNCTION();
       
   943 
       
   944     setState(Stopping);
       
   945     MvruoEvent(TMMFEvent(KCamCControllerCCVideoRecordStopped, KErrNone));
       
   946     MvruoEvent(TMMFEvent(KCamCControllerCCVideoFileComposed, KErrNone));
       
   947 
       
   948     CX_DEBUG_EXIT_FUNCTION();
       
   949 }
  1319 // End of file
   950 // End of file