javauis/mmapi_akn/baseline/src.nga/cmmacameraplayer.cpp
branchRCL_3
changeset 60 6c158198356e
child 77 7cee158cb8cd
equal deleted inserted replaced
59:e5618cc85d74 60:6c158198356e
       
     1 /*
       
     2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This class is used for playing camera.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 //  INCLUDE FILES
       
    20 #include <sensrvchannelfinder.h>
       
    21 #include <sensrvorientationsensor.h>
       
    22 #include <jdebug.h>
       
    23 #include <fbs.h>
       
    24 #include <e32svr.h>
       
    25 #include "cmmacameraplayer.h"
       
    26 #include "tmmaparametervalidator.h"
       
    27 #include "mmmadisplay.h"
       
    28 #include "cmmacamerasound.h"
       
    29 
       
    30 #if defined( __WINS__ )
       
    31 #include <w32std.h>
       
    32 #endif
       
    33 
       
    34 // CONSTANTS
       
    35 _LIT8(KImageJpegMime, "image/jpeg");
       
    36 _LIT8(KJpegMime, "jpeg");
       
    37 _LIT(KVideoControlName, "VideoControl");
       
    38 
       
    39 CMMACameraPlayer* CMMACameraPlayer::NewLC(TCamActiveCamera aCameraIndex)
       
    40 {
       
    41     CMMACameraPlayer* self = new(ELeave) CMMACameraPlayer(aCameraIndex);
       
    42     CleanupStack::PushL(self);
       
    43     self->ConstructL(aCameraIndex);
       
    44     return self;
       
    45 }
       
    46 
       
    47 CMMACameraPlayer::~CMMACameraPlayer()
       
    48 {
       
    49     DEBUG("CMMACameraPlayer::~CMMACameraPlayer +");
       
    50 
       
    51     // Free (duplicated) UI camera resources first.
       
    52     // Window is not able to send any
       
    53     // callback requests to UI from now.
       
    54     if (iWindow)
       
    55     {
       
    56         iWindow->SetDisplay(NULL);
       
    57     }
       
    58 
       
    59     if (iCamera)
       
    60     {
       
    61         iCamera->CancelCaptureImage();
       
    62         iCamera->Release();
       
    63         delete iCamera;
       
    64     }
       
    65 
       
    66     delete iSnapshotEncoded;
       
    67     delete iSnapshotBitmap;
       
    68     delete iRealizeWait;
       
    69 
       
    70     if (iDisplay && iDisplay->HasContainer())
       
    71     {
       
    72         // Window will delete itself
       
    73         // after all pending events are processed
       
    74         // (lazy delete)
       
    75         iDisplay->UIGetCallback(
       
    76             *iWindow, CMMACameraWindow::EDestroyWindow);
       
    77     }
       
    78     else
       
    79     {
       
    80         delete iWindow;
       
    81     }
       
    82     iWindow = NULL;
       
    83     // Delete sensor api object
       
    84     delete iAccSensorChannel;
       
    85     DEBUG("CMMACameraPlayer::~CMMACameraPlayer -");
       
    86 }
       
    87 
       
    88 
       
    89 CMMACameraPlayer::CMMACameraPlayer(TCamActiveCamera aCameraIndex):
       
    90         iDisplay(NULL),
       
    91         iSourceSizeIndex(KErrNotFound),
       
    92         iStartTime(KErrNotFound),
       
    93         iSnapshotEncoded(NULL),
       
    94         iActiveCameraIndex(aCameraIndex),
       
    95         iImageOrientation(ECamOrientation0),
       
    96         iLastImageOrientation(ECamOrientation0)
       
    97 {
       
    98     iStopViewFinder = ETrue;
       
    99 }
       
   100 
       
   101 
       
   102 void CMMACameraPlayer::ConstructL(TCamActiveCamera aCameraIndex)
       
   103 {
       
   104     CMMAPlayer::ConstructL();
       
   105 
       
   106     if (aCameraIndex >= CCamera::CamerasAvailable())
       
   107     {
       
   108         // image capture is not supported
       
   109         User::Leave(KErrNotFound);
       
   110     }
       
   111 
       
   112     iCamera = CCamera::New2L(*this, aCameraIndex, 100);
       
   113 
       
   114     iCustomInterfaceOrientation =
       
   115       static_cast <MCameraOrientation*>(
       
   116         iCamera->CustomInterface(KCameraOrientationUid ));
       
   117     iCustomInterfaceUIOrientationOverride =
       
   118       static_cast <MCameraUIOrientationOverride*>(
       
   119       iCamera->CustomInterface(KCameraUIOrientationOverrideUid));
       
   120     // Fix to landscape mode
       
   121     iCustomInterfaceUIOrientationOverride->SetOrientationModeL(1);
       
   122 
       
   123     iWindow = CMMACameraWindow::NewL(iCamera->Handle());
       
   124 
       
   125     TCameraInfo cameraInfo;
       
   126     iCamera->CameraInfo(cameraInfo);
       
   127 
       
   128     if (cameraInfo.iNumImageSizesSupported < 1)
       
   129     {
       
   130         // image capture is not supported
       
   131         User::Leave(KErrNotFound);
       
   132     }
       
   133 
       
   134     // default snapshot size
       
   135     iSourceSizeIndex = cameraInfo.iNumImageSizesSupported - 1;
       
   136 
       
   137     iRealizeWait = new(ELeave)CRealizeWait;
       
   138 }
       
   139 
       
   140 TInt64 CMMACameraPlayer::CurrentTime()
       
   141 {
       
   142     TTime time;
       
   143     time.HomeTime();
       
   144     return time.Int64();
       
   145 }
       
   146 
       
   147 void CMMACameraPlayer::ResolveViewFinderSizeL(TSize& aSize)
       
   148 {
       
   149     DEBUG("CMMACameraPlayer::ResolveViewFinderSizeL");
       
   150 
       
   151     TSize resultSize;
       
   152 
       
   153     // The only way to find out the size is to start the view finder
       
   154     // with a proper size (screen size).
       
   155 
       
   156     ResolveScreenSizeL(resultSize);
       
   157 
       
   158     // StartViewFinderBitmapsL changes resultSize to
       
   159     // the used view finder size.
       
   160     // Used to get the source size only.
       
   161     iCamera->StartViewFinderBitmapsL(resultSize);
       
   162 
       
   163     // Bitmap viewfinder is not used anymore.
       
   164     iCamera->StopViewFinder();
       
   165 
       
   166     aSize = resultSize;
       
   167 }
       
   168 
       
   169 void CMMACameraPlayer::ResolveScreenSizeL(TSize& aSize)
       
   170 {
       
   171     DEBUG("CMMACameraPlayer::ResolveScreenSizeL");
       
   172 
       
   173 #if defined( __WINS__ )
       
   174     TSize size(0,0);
       
   175     RWsSession ws;
       
   176 
       
   177     if (ws.Connect() == KErrNone)
       
   178     {
       
   179         CleanupClosePushL(ws);
       
   180 
       
   181         CWsScreenDevice* wsScreenDevice = new(ELeave)CWsScreenDevice(ws);
       
   182         CleanupStack::PushL(wsScreenDevice);
       
   183 
       
   184         User::LeaveIfError(wsScreenDevice->Construct());
       
   185 
       
   186         size = wsScreenDevice->SizeInPixels();
       
   187 
       
   188         CleanupStack::PopAndDestroy(2);    // wsScreenDevice, ws.Close()
       
   189     }
       
   190 
       
   191     aSize = size;
       
   192 
       
   193 #else
       
   194     TScreenInfoV01 info;
       
   195     TPckgBuf< TScreenInfoV01 > buf(info);
       
   196 
       
   197     UserSvr::ScreenInfo(buf);
       
   198     info = buf();
       
   199 
       
   200     aSize = info.iScreenSize;
       
   201 #endif
       
   202 }
       
   203 
       
   204 void CMMACameraPlayer::ResolveCaptureSizes(const CCamera::TFormat aFormat,
       
   205         const TInt aNumImageSizesSupported,
       
   206         const TSize& aRequestSize,
       
   207         TSize& aSourceSize,
       
   208         TInt& aSourceIndex,
       
   209         TInt& aLargestIndex)
       
   210 {
       
   211     // Largest image size
       
   212     TSize largestSize;
       
   213     // Index to largest image size
       
   214     TInt largestSizeIndex = 0;
       
   215     // Source size
       
   216     TSize sourceSize;
       
   217     // Default source size index not set
       
   218     TInt sourceSizeIndex = KErrNotFound;
       
   219     // Temporary size for iterating capture sizes
       
   220     TSize tmpSize;
       
   221 
       
   222     DEBUG_INT("MMA::CMMACameraPlayer::ResolveCaptureSizes: aFormat = 0x%x", aFormat);
       
   223 
       
   224     // go through all supported sizes.
       
   225     // Notice: Capture sizes are assumed to be in order from smaller to larger sizes
       
   226     for (TInt i = 0; i < aNumImageSizesSupported; i++)
       
   227     {
       
   228         iCamera->EnumerateCaptureSizes(tmpSize,
       
   229                                        i,
       
   230                                        aFormat);
       
   231 
       
   232         DEBUG_INT("MMA::CMMACameraPlayer::ResolveCaptureSizes: tmpSize.iWidth = %d", tmpSize.iWidth);
       
   233         DEBUG_INT("MMA::CMMACameraPlayer::ResolveCaptureSizes: tmpSize.iHeight = %d", tmpSize.iHeight);
       
   234 
       
   235         // Check if current is the largest
       
   236         if ((largestSize.iWidth < tmpSize.iWidth) &&
       
   237                 (largestSize.iHeight < tmpSize.iHeight))
       
   238         {
       
   239             largestSize = tmpSize;
       
   240             largestSizeIndex = i;
       
   241         }
       
   242 
       
   243         // If wanted size is smaller than tmpSize we can use it
       
   244         if ((aRequestSize.iWidth <= tmpSize.iWidth) &&
       
   245                 (aRequestSize.iHeight <= tmpSize.iHeight))
       
   246         {
       
   247             sourceSize = tmpSize;
       
   248             sourceSizeIndex = i;
       
   249         }
       
   250     }
       
   251 
       
   252     DEBUG_INT("MMA::CMMACameraPlayer::ResolveCaptureSizes: sourceSizeIndex = %d", sourceSizeIndex);
       
   253     DEBUG_INT("MMA::CMMACameraPlayer::ResolveCaptureSizes: largestSizeIndex = %d", largestSizeIndex);
       
   254 
       
   255     aSourceSize = sourceSize;
       
   256     aSourceIndex = sourceSizeIndex;
       
   257     aLargestIndex = largestSizeIndex;
       
   258 }
       
   259 
       
   260 void CMMACameraPlayer::StartL(TBool aPostEvent)
       
   261 {
       
   262     DEBUG_INT("CMMACameraPlayer:StartL iState %d", iState);
       
   263 
       
   264     // start can't be called to not ready player
       
   265     if (iState == EPrefetched)
       
   266     {
       
   267         // camera passes ready images through
       
   268         // ViewFinderFrameReady method
       
   269 
       
   270         // set time when started
       
   271         iStartTime = CurrentTime();
       
   272 
       
   273         // inform java side
       
   274         ChangeState(EStarted);
       
   275 
       
   276         TInt64 time;
       
   277         GetMediaTime(&time);
       
   278 
       
   279         // Notify the camera window
       
   280         // about the status change
       
   281         iWindow->SetStarted(ETrue);
       
   282 
       
   283         if (aPostEvent)
       
   284         {
       
   285             // inform java side
       
   286             PostLongEvent(CMMAPlayerEvent::EStarted, time);
       
   287         }
       
   288     }
       
   289     PostActionCompleted(KErrNone);   // java start return
       
   290 }
       
   291 
       
   292 void CMMACameraPlayer::StopL(TBool aPostEvent)
       
   293 {
       
   294     DEBUG_INT("CMMACameraPlayer::StopL", iState);
       
   295     if (iState == EStarted)
       
   296     {
       
   297         TInt64 time;
       
   298         GetMediaTime(&time);   // add played time to media time
       
   299 
       
   300         if (iStopViewFinder && iWindow->ViewFinderActive())
       
   301         {
       
   302             iWindow->SetStarted(EFalse);
       
   303         }
       
   304         iStartTime = KErrNotFound;
       
   305 
       
   306         if (aPostEvent)
       
   307         {
       
   308             PostLongEvent(CMMAPlayerEvent::EStopped, time);
       
   309         }
       
   310 
       
   311         // go back to prefetched state
       
   312         ChangeState(EPrefetched);
       
   313     }
       
   314 }
       
   315 
       
   316 void CMMACameraPlayer::DeallocateL()
       
   317 {
       
   318     // If player is started when deallocate is called,
       
   319     // player is stopped from java side -> state is changed to
       
   320     // prefetched.
       
   321     // In prefetched state only reserved resource is
       
   322     // camera reserve( released with iCamera->Release() )
       
   323     // In realized state no resources have been reserved.
       
   324     // CHANGED: not releasing camera anymore, since it is already
       
   325     // done in realized state
       
   326     if (iState == EPrefetched)
       
   327     {
       
   328         ChangeState(ERealized);
       
   329     }
       
   330 }
       
   331 
       
   332 
       
   333 void CMMACameraPlayer::RealizeL()
       
   334 {
       
   335     iCamera->Reserve();
       
   336     // this lock will be released when power on is completed (or error)
       
   337     if (!iRealizeWait->IsStarted())
       
   338     {
       
   339         iRealizeWait->Start();
       
   340     }
       
   341     User::LeaveIfError(iRealizeWait->iError);
       
   342     CMMAPlayer::RealizeL();
       
   343 }
       
   344 
       
   345 
       
   346 void CMMACameraPlayer::PrefetchL()
       
   347 {
       
   348     DEBUG("MMA::CMMACameraPlayer::PrefetchL");
       
   349     // nothing to do here
       
   350     ChangeState(EPrefetched);
       
   351     PostActionCompleted(KErrNone);
       
   352 }
       
   353 
       
   354 
       
   355 void CMMACameraPlayer::GetDuration(TInt64* aDuration)
       
   356 {
       
   357     // camera viewer has no duration.
       
   358     *aDuration = KTimeUnknown;
       
   359 }
       
   360 
       
   361 
       
   362 void CMMACameraPlayer::SetMediaTimeL(TInt64* /*aTime*/)
       
   363 {
       
   364     DEBUG("MMA::CMMACameraPlayer::SetMediaTimeL ");
       
   365     // with camera media time is not supported.
       
   366 }
       
   367 
       
   368 
       
   369 void CMMACameraPlayer::GetMediaTime(TInt64* aMediaTime)
       
   370 {
       
   371     if (iState == EStarted)
       
   372     {
       
   373         // add play time to media time
       
   374         iMediaTime += CurrentTime() - iStartTime;
       
   375         // set new start time
       
   376         iStartTime = CurrentTime();
       
   377     }
       
   378 
       
   379     // set value to parameter
       
   380     (*aMediaTime) = iMediaTime;
       
   381 }
       
   382 
       
   383 void CMMACameraPlayer::CloseL()
       
   384 {
       
   385     DEBUG("MMA::CMMACameraPlayer::CloseL()");
       
   386 
       
   387     // cancel all activity
       
   388     iCamera->CancelCaptureImage();
       
   389 
       
   390     // Stop and release UI Camera instance
       
   391     iWindow->SetDisplay(NULL);
       
   392 
       
   393     // we don't need reserve camera anymore
       
   394     iCamera->Release();
       
   395 
       
   396     iCustomInterfaceOrientation = NULL;
       
   397     if (iAccSensorChannel)
       
   398     {
       
   399         iAccSensorChannel->StopDataListening();
       
   400     }
       
   401 
       
   402     if (iDisplay)
       
   403     {
       
   404         iDisplay->FixUIOrientation(EFalse);
       
   405     }
       
   406 
       
   407     CMMAPlayer::CloseL();
       
   408 }
       
   409 
       
   410 const TDesC& CMMACameraPlayer::Type()
       
   411 {
       
   412     return KMMACameraPlayer;
       
   413 }
       
   414 
       
   415 
       
   416 void CMMACameraPlayer::HandleEvent(const TECAMEvent& aEvent)
       
   417 {
       
   418     TInt error = aEvent.iErrorCode;
       
   419     if (KUidECamEventReserveComplete == aEvent.iEventType)
       
   420     {
       
   421         DEBUG_INT("MMA::CMMACameraPlayer::HandleEvent:KUidECamEventReserveComplete error  %d", error);
       
   422         if (error == KErrNone)
       
   423         {
       
   424             // camera will notify completion with PowerOnComplete method.
       
   425             iCamera->PowerOn();
       
   426         }
       
   427         else
       
   428         {
       
   429             // release lock and store error. State doesn't change.
       
   430             iRealizeWait->iError = error;
       
   431             iRealizeWait->AsyncStop();
       
   432         }
       
   433     }
       
   434     else if (KUidECamEventPowerOnComplete == aEvent.iEventType)
       
   435     {
       
   436         DEBUG_INT("MMA::CMMACameraPlayer::HandleEvent:KUidECamEventPowerOnComplete error  %d", error);
       
   437 
       
   438         TSize viewFinderSize;
       
   439 
       
   440         if (error == KErrNone)
       
   441         {
       
   442             // The view finder size must be known after prefetching.
       
   443             TRAP(error, ResolveViewFinderSizeL(viewFinderSize));
       
   444         }
       
   445 
       
   446         if (error == KErrNone)
       
   447         {
       
   448             iSize = viewFinderSize;
       
   449 
       
   450             if (iDisplay)
       
   451             {
       
   452                 iDisplay->SourceSizeChanged(iSize);
       
   453                 NotifyWithStringEvent(CMMAPlayerEvent::ESizeChanged, KVideoControlName);
       
   454 
       
   455                 iDisplay->FixUIOrientation(ETrue);
       
   456             }
       
   457         }
       
   458 
       
   459         iRealizeWait->iError = error;
       
   460         iRealizeWait->AsyncStop();
       
   461     }
       
   462 }
       
   463 
       
   464 void CMMACameraPlayer::ViewFinderReady(MCameraBuffer& aCameraBuffer,
       
   465                                        TInt /*aError*/)
       
   466 {
       
   467     aCameraBuffer.Release();
       
   468 }
       
   469 	
       
   470 void CMMACameraPlayer::ImageBufferReady(MCameraBuffer& aCameraBuffer,TInt aError)
       
   471 {
       
   472     DEBUG_INT("MMA::CMMACameraPlayer::ImageBufferReady %d", aError);
       
   473 
       
   474     // This method should never be called,
       
   475     // unless we are taking snapshot
       
   476     __ASSERT_DEBUG(iSnapshotStatus, User::Invariant());
       
   477     __ASSERT_DEBUG(!iSnapshotBitmap, User::Invariant());
       
   478     __ASSERT_DEBUG(!iSnapshotEncoded, User::Invariant());
       
   479 
       
   480     TInt error = aError;
       
   481     if (aError == KErrNone)
       
   482     {
       
   483         CFbsBitmap* srcBitmap = NULL;
       
   484         TRAP(error, HandleBitmapCopyL(aCameraBuffer, srcBitmap));
       
   485         DEBUG_INT("MMA::CMMACameraPlayer::ImageBufferReady HandleBitmapCopyL %d", error);
       
   486 
       
   487         // picture data is not of bitmap type
       
   488         if (!srcBitmap && (KErrNotSupported == error))
       
   489         {
       
   490             TDesC8* temp = NULL;
       
   491             TRAP(error, temp = aCameraBuffer.DataL(0));
       
   492             DEBUG_INT("CMMACameraPlayer::CopyImageDataL DataL error %d", error);
       
   493             if (KErrNone == error)
       
   494             {
       
   495                 iSnapshotEncoded = temp->Alloc();
       
   496             }
       
   497         }
       
   498     }
       
   499 
       
   500     // notify the caller, error code or KErrNone
       
   501     User::RequestComplete(iSnapshotStatus, error);
       
   502     iWindow->SetStarted(ETrue);
       
   503     // Status is not needed anymore
       
   504     // and this class don't own the status.
       
   505     iSnapshotStatus = NULL;
       
   506     aCameraBuffer.Release();
       
   507 }
       
   508 
       
   509 void CMMACameraPlayer::VideoBufferReady(MCameraBuffer& aCameraBuffer,
       
   510                                         TInt /*aError*/)
       
   511 {
       
   512     aCameraBuffer.Release();
       
   513 }
       
   514 
       
   515 void CMMACameraPlayer::HandleBitmapCopyL(MCameraBuffer& aCameraBuffer, 
       
   516                                          CFbsBitmap* aSrcBitmap)
       
   517 {
       
   518     DEBUG("MMA::CMMACameraPlayer::HandleBitmapCopyL +");
       
   519     
       
   520     aSrcBitmap = &(aCameraBuffer.BitmapL(0)); // not owned
       
   521 
       
   522     iSnapshotBitmap = new(ELeave)CFbsBitmap();
       
   523 
       
   524     User::LeaveIfError(iSnapshotBitmap->Create(aSrcBitmap->SizeInPixels(),
       
   525                                              aSrcBitmap->DisplayMode()));
       
   526     CFbsBitmapDevice* bitmapDevice = NULL;
       
   527     CFbsBitGc* bitmapGc = NULL;
       
   528 
       
   529     bitmapDevice = CFbsBitmapDevice::NewL(iSnapshotBitmap);
       
   530     bitmapDevice->CreateContext(bitmapGc);
       
   531     bitmapGc->BitBlt(TPoint(0,0), aSrcBitmap);
       
   532 
       
   533     delete bitmapGc;
       
   534     delete bitmapDevice;
       
   535     DEBUG("MMA::CMMACameraPlayer::HandleBitmapCopyL -");
       
   536 }
       
   537 
       
   538 void CMMACameraPlayer::SetDisplayL(MMMADisplay* aDisplay)
       
   539 {
       
   540     DEBUG("MMA::CMMACameraPlayer::SetDisplay");
       
   541 
       
   542     // now it is ready to draw
       
   543     iDisplay = aDisplay;
       
   544 
       
   545     // Passes display into iWindow.
       
   546     // Allocates all resources needed to use a camera DirectViewFinder.
       
   547     iWindow->SetDisplay(aDisplay);
       
   548 
       
   549     iDisplay->SetWindowL(iWindow);
       
   550 
       
   551     // Set view finder size to the display only if the view finder
       
   552     // size has been resolved.
       
   553     if (iSize != TSize(0, 0))
       
   554     {
       
   555         iDisplay->SourceSizeChanged(iSize);
       
   556         NotifyWithStringEvent(CMMAPlayerEvent::ESizeChanged, KVideoControlName);
       
   557     }
       
   558 
       
   559     iDisplay->FixUIOrientation(ETrue);
       
   560     UpdateSensorInfoL();
       
   561 }
       
   562 
       
   563 TSize CMMACameraPlayer::SourceSize()
       
   564 {
       
   565     return iSize;
       
   566 }
       
   567 
       
   568 MMMASnapshot::TEncoding CMMACameraPlayer::TakeSnapshotL(TRequestStatus* aStatus,
       
   569         const TSize& aSize,
       
   570         const CMMAImageSettings& aSettings)
       
   571 {
       
   572     __ASSERT_DEBUG(!iSnapshotStatus, User::Invariant());
       
   573     __ASSERT_DEBUG(!iSnapshotBitmap, User::Invariant());
       
   574     __ASSERT_DEBUG(!iSnapshotEncoded, User::Invariant());
       
   575 
       
   576     // snapshots can not be taken if player is not realized
       
   577     if (iState < ERealized)
       
   578     {
       
   579         User::Leave(KErrNotReady);
       
   580     }
       
   581     // save status which will be notified
       
   582     iSnapshotStatus = aStatus;
       
   583 
       
   584     // changing status to pending
       
   585     *iSnapshotStatus = KRequestPending;
       
   586 
       
   587     // Source size not set in the beginning
       
   588     TSize sourceSize;
       
   589 
       
   590     // Use default if size is not specified.
       
   591     TInt sourceSizeIndex;
       
   592     
       
   593     if (aSize.iWidth != KErrNotFound &&
       
   594             aSize.iHeight != KErrNotFound)
       
   595         {
       
   596         sourceSizeIndex = iSourceSizeIndex;
       
   597         }
       
   598     else
       
   599         {
       
   600         sourceSizeIndex = 0;
       
   601         }
       
   602     
       
   603     // Largest image size index
       
   604     TInt largestSizeIndex = 0;
       
   605 
       
   606     // Get camera characteristics
       
   607     TCameraInfo cameraInfo;
       
   608     iCamera->CameraInfo(cameraInfo);
       
   609 
       
   610     // Set default snapshot encoding type
       
   611     TEncoding encoding = EEncoded;
       
   612     // Set default image capture format
       
   613     CCamera::TFormat format = CCamera::EFormatExif;
       
   614 
       
   615     DEBUG_INT("MMA::CMMACameraPlayer::TakeSnapshotL: cameraInfo.iImageFormatsSupported = 0x%x", cameraInfo.iImageFormatsSupported);
       
   616     DEBUG_INT("MMA::CMMACameraPlayer::TakeSnapshotL: cameraInfo.iNumImageSizesSupported = %d", cameraInfo.iNumImageSizesSupported);
       
   617 
       
   618     // Check if size was set in Java
       
   619     if (aSize.iWidth != KErrNotFound &&
       
   620             aSize.iHeight != KErrNotFound)
       
   621     {
       
   622         DEBUG("MMA::CMMACameraPlayer::TakeSnapshotL size was set in MIDlet");
       
   623         // Determine if jpeg capture was requested
       
   624         if ((*aSettings.iMimeType == KJpegMime) ||
       
   625                 (*aSettings.iMimeType == KImageJpegMime))
       
   626         {
       
   627             // Shortcut for supported image formats
       
   628             TUint32 imageFormats = cameraInfo.iImageFormatsSupported;
       
   629 
       
   630             // Jpeg subtype constants
       
   631             _LIT8(KJpegJfif, "jfif");
       
   632             _LIT8(KJpegExif, "exif");
       
   633 
       
   634             // Resolve requested jpeg subtype from settings and camerainfo
       
   635             if ((imageFormats & CCamera::EFormatJpeg) &&
       
   636                     (*aSettings.iType == KJpegJfif))
       
   637             {
       
   638                 // JFIF JPEG
       
   639                 format = CCamera::EFormatJpeg;
       
   640                 encoding = EEncoded;
       
   641             }
       
   642             else if ((imageFormats & CCamera::EFormatExif) &&
       
   643                      (*aSettings.iType == KJpegExif))
       
   644             {
       
   645                 // EXIF JPEG
       
   646                 format =  CCamera::EFormatExif;
       
   647                 encoding = EEncoded;
       
   648             }
       
   649         }
       
   650 
       
   651         // Try to resolve nearest source size to the one requested,
       
   652         // except for the JFIF and EXIF jpeg subtypes the match has
       
   653         // to be exact otherwise non-encode capture format will be
       
   654         // used
       
   655         ResolveCaptureSizes(format,
       
   656                             cameraInfo.iNumImageSizesSupported,
       
   657                             aSize,
       
   658                             sourceSize,
       
   659                             sourceSizeIndex,
       
   660                             largestSizeIndex);
       
   661 
       
   662         // Format was either of the jpeg formats and requested size
       
   663         // didn't match the source size
       
   664         if ((format >= CCamera::EFormatJpeg &&
       
   665                 format <= CCamera::EFormatExif) &&
       
   666                 (aSize != sourceSize))
       
   667         {
       
   668             // Try again with an non-encoded format
       
   669             format = CCamera::EFormatFbsBitmapColor16M;
       
   670             encoding = EBitmap;
       
   671             ResolveCaptureSizes(format,
       
   672                                 cameraInfo.iNumImageSizesSupported,
       
   673                                 aSize,
       
   674                                 sourceSize,
       
   675                                 sourceSizeIndex,
       
   676                                 largestSizeIndex);
       
   677         }
       
   678 
       
   679         if (sourceSizeIndex == KErrNotFound)
       
   680         {
       
   681             // If correct index was not found use the largest.
       
   682             sourceSizeIndex = largestSizeIndex;
       
   683         }
       
   684     }
       
   685     // else use default iSourceSizeIndex and default image capture format
       
   686 
       
   687     iCamera->PrepareImageCaptureL(format,
       
   688                                   sourceSizeIndex);
       
   689 
       
   690     // play sound when capturing image
       
   691     CMMACameraSound::PlayImageCaptureSoundL();
       
   692 
       
   693     // start capture, ImageBufferReady will be called when ready
       
   694     iWindow->SetStarted(EFalse);
       
   695 
       
   696     iCamera->CaptureImage();
       
   697 
       
   698     DEBUG_INT("MMA::CMMACameraPlayer::TakeSnapshotL: format = 0x%x", format);
       
   699     DEBUG_INT("MMA::CMMACameraPlayer::TakeSnapshotL: sourceSizeIndex = %d", sourceSizeIndex);
       
   700     DEBUG_INT("MMA::CMMACameraPlayer::TakeSnapshotL: encoding = %d", encoding);
       
   701 
       
   702     // Inform caller which snapshot encoding was ultimately used
       
   703     return encoding;
       
   704 }
       
   705 
       
   706 CFbsBitmap* CMMACameraPlayer::SnapshotBitmap()
       
   707 {
       
   708     CFbsBitmap* bitmap = iSnapshotBitmap;
       
   709 
       
   710     // ownership transfers to the caller
       
   711     iSnapshotBitmap = NULL;
       
   712     return bitmap;
       
   713 }
       
   714 
       
   715 HBufC8* CMMACameraPlayer::SnapshotEncoded()
       
   716 {
       
   717     HBufC8* encoded = iSnapshotEncoded;
       
   718 
       
   719     // ownership transfers to the caller
       
   720     iSnapshotEncoded = NULL;
       
   721     return encoded;
       
   722 }
       
   723 
       
   724 void CMMACameraPlayer::NotifyWithStringEvent(
       
   725     CMMAPlayerEvent::TEventType aEventType,
       
   726     const TDesC& aStringEventData)
       
   727 {
       
   728     PostStringEvent(aEventType, aStringEventData);
       
   729 }
       
   730 
       
   731 MMMASnapshot* CMMACameraPlayer::SnapshoterL()
       
   732 {
       
   733     return this;
       
   734 }
       
   735 
       
   736 TInt CMMACameraPlayer::CameraHandle()
       
   737 {
       
   738     return iCamera->Handle();
       
   739 }
       
   740 
       
   741 void CMMACameraPlayer::SetViewFinderMode(TBool aStopViewFinder)
       
   742 {
       
   743     iStopViewFinder = aStopViewFinder;
       
   744 }
       
   745 
       
   746 void CMMACameraPlayer::UpdateSensorInfoL()
       
   747 {
       
   748     DEBUG("CMMACameraPlayer::UpdateSensorInfoL +");
       
   749     CSensrvChannelFinder* channelFinder;
       
   750     channelFinder = CSensrvChannelFinder::NewL();
       
   751     CleanupStack::PushL(channelFinder);
       
   752 
       
   753     //List of found channels.
       
   754     RSensrvChannelInfoList channelInfoList;
       
   755     CleanupClosePushL(channelInfoList);
       
   756 
       
   757     //Create and fill channel search criteria.
       
   758     TSensrvChannelInfo channelInfo;
       
   759     channelInfo.iChannelType = KSensrvChannelTypeIdOrientationData;
       
   760     //Find the orientation channel
       
   761     channelFinder->FindChannelsL(channelInfoList, channelInfo);
       
   762 
       
   763     if(channelInfoList.Count() != 1)
       
   764     {
       
   765         DEBUG("CMMACameraPlayer::UpdateSensorInfoL, Orientation channel not found");
       
   766         User::Leave( KErrNotSupported );
       
   767     }
       
   768     else
       
   769     {
       
   770         DEBUG("CMMACameraPlayer::UpdateSensorInfoL, Orientation channel found");
       
   771     }
       
   772 
       
   773     iAccSensorChannel = CSensrvChannel::NewL(channelInfoList[ 0 ]);
       
   774     CleanupStack::PopAndDestroy(&channelInfoList);
       
   775     CleanupStack::PopAndDestroy(channelFinder);
       
   776 
       
   777     TRAPD(channelerror, iAccSensorChannel->OpenChannelL());
       
   778     if (channelerror!=KErrNone)
       
   779     {
       
   780         User::Leave( channelerror );
       
   781     }
       
   782     
       
   783     // start listening
       
   784     iAccSensorChannel->StartDataListeningL(this, //this object is data listener for this channel
       
   785                                             1, //aDesiredCount is one, i.e. each orientation change is notified separately
       
   786                                             1, //aMaximumCount is one, i.e. object count in receiving data buffer is one
       
   787                                             0);//buffering period is not used
       
   788     iLastImageOrientation = ECamOrientation0;
       
   789     DEBUG("CMMACameraPlayer::UpdateSensorInfoL -");
       
   790 }
       
   791 
       
   792 void CMMACameraPlayer::DataReceived(CSensrvChannel& aChannel,
       
   793                                     TInt /*aCount*/, 
       
   794                                     TInt /*aDataLost*/)
       
   795 {
       
   796     DEBUG_INT("CMMACameraPlayer::DataReceived aChannel %d", aChannel.GetChannelInfo().iChannelType);
       
   797 
       
   798     if (KSensrvChannelTypeIdOrientationData == aChannel.GetChannelInfo().iChannelType)
       
   799     {
       
   800         TSensrvOrientationData orientationData;
       
   801         TPckg<TSensrvOrientationData> orientationPackage(orientationData);
       
   802         aChannel.GetData(orientationPackage);
       
   803 
       
   804         iImageOrientation =
       
   805                 MapSensorOrientatio2CamOrientation(orientationData.iDeviceOrientation, 
       
   806                                                    iLastImageOrientation,
       
   807                                                    iActiveCameraIndex);
       
   808 
       
   809         TRAPD(error, iCustomInterfaceOrientation->SetOrientationL(Map2CameraOrientation(iImageOrientation)));
       
   810         if (KErrNone == error)
       
   811         {
       
   812             DEBUG_INT("CMMACameraPlayer::DataReceived SetOrientationL error = %d", error);
       
   813         }
       
   814 
       
   815         iLastImageOrientation = iImageOrientation;
       
   816     }
       
   817 }
       
   818 
       
   819 void CMMACameraPlayer::DataError(CSensrvChannel& /*aChannel*/,
       
   820                                  TSensrvErrorSeverity aError)
       
   821 {
       
   822     DEBUG_INT("MMA::CMMACameraPlayer::DataError: aError = %d", aError);
       
   823     if ( ESensrvErrorSeverityFatal == aError ) 
       
   824     {
       
   825         // Delete sensor api object
       
   826         delete iAccSensorChannel;
       
   827         iAccSensorChannel = NULL;
       
   828 
       
   829         // Set orientation back to default if not already there.
       
   830         iImageOrientation   = ECamOrientation0;
       
   831     }
       
   832 }
       
   833 
       
   834 void CMMACameraPlayer::GetDataListenerInterfaceL(TUid /*aInterfaceUid*/,
       
   835                                                  TAny*& /*aInterface*/)
       
   836 {
       
   837 }
       
   838 
       
   839 TCamImageOrientation CMMACameraPlayer::MapSensorOrientatio2CamOrientation( 
       
   840     const TSensrvOrientationData::TSensrvDeviceOrientation& aSensorOrientation, 
       
   841     TCamImageOrientation aLastImageOrientation,
       
   842     TCamActiveCamera aActiveCameraIndex)
       
   843 {
       
   844     DEBUG_INT("MMA::CMMACameraPlayer::MapSensorOrientatio2CamOrientation: aSensorOrientation = %d", 
       
   845     aSensorOrientation);
       
   846 
       
   847     TCamImageOrientation cameraOrientation( ECamOrientation0 );
       
   848 
       
   849     // Primary camera rotation
       
   850     if (aActiveCameraIndex == ECamActiveCameraPrimary) 
       
   851     {
       
   852       switch(aSensorOrientation)
       
   853       {
       
   854         case TSensrvOrientationData::EOrientationDisplayUpwards:
       
   855             DEBUG("CMMACameraPlayer::MapSensorOrientatio2CamOrientation EOrientationDisplayUpwards");
       
   856             // If coming from upside down portrait...
       
   857             if ( ECamOrientation270 == aLastImageOrientation )
       
   858             {
       
   859                 // Switch from upside down portrait to normal portrait.") )
       
   860                 cameraOrientation = ECamOrientation90; // Set normal portrait
       
   861             }
       
   862             // If coming from upside down landscape...
       
   863             else if ( ECamOrientation180 == aLastImageOrientation )
       
   864             {
       
   865                 // Switch from upside down landscape to normal landscape...") )
       
   866                 cameraOrientation = ECamOrientation0; // Set normal lanscape
       
   867             }
       
   868             // If neither one, keep the current image orientation.
       
   869             else
       
   870             {
       
   871                 cameraOrientation = ECamOrientationIgnore;
       
   872             }
       
   873             break;
       
   874 
       
   875         case TSensrvOrientationData::EOrientationDisplayDownwards:
       
   876             DEBUG("CMMACameraPlayer::MapSensorOrientatio2CamOrientation EOrientationDisplayDownwards");
       
   877             // Camera is pointing up now. Check if it was upside down previously.
       
   878             // If coming from upside down portrait...
       
   879             if ( ECamOrientation270 == aLastImageOrientation )
       
   880             {
       
   881                 // Switch from upside down portrait to normal portrait...") )
       
   882                 cameraOrientation = ECamOrientation90; // Set normal portrait
       
   883             }
       
   884             // If coming from upside down landscape...
       
   885             else if ( ECamOrientation180 == aLastImageOrientation )
       
   886             {
       
   887                 // Switch from upside down landscape to normal landscape...") )
       
   888                 cameraOrientation = ECamOrientation0; // Set normal lanscape
       
   889             }
       
   890             // If neither one, keep the current image orientation.
       
   891             else
       
   892             {
       
   893                 cameraOrientation = ECamOrientationIgnore;
       
   894             }
       
   895         	  break;
       
   896         case TSensrvOrientationData::EOrientationDisplayRightUp:
       
   897             DEBUG("CMMACameraPlayer::MapSensorOrientatio2CamOrientation EOrientationDisplayRightUp");
       
   898         case TSensrvOrientationData::EOrientationUndefined:
       
   899             DEBUG("CMMACameraPlayer::MapSensorOrientatio2CamOrientation EOrientationUndefined");
       
   900             cameraOrientation = ECamOrientation0;     
       
   901             break;
       
   902         case TSensrvOrientationData::EOrientationDisplayUp:
       
   903             DEBUG("CMMACameraPlayer::MapSensorOrientatio2CamOrientation EOrientationDisplayUp");
       
   904             cameraOrientation = ECamOrientation90;
       
   905             break;
       
   906         case TSensrvOrientationData::EOrientationDisplayLeftUp:
       
   907             DEBUG("CMMACameraPlayer::MapSensorOrientatio2CamOrientation EOrientationDisplayLeftUp");
       
   908             cameraOrientation = ECamOrientation180;
       
   909             break;
       
   910         case TSensrvOrientationData::EOrientationDisplayDown:
       
   911             DEBUG("CMMACameraPlayer::MapSensorOrientatio2CamOrientation EOrientationDisplayDown");
       
   912             cameraOrientation = ECamOrientation270;
       
   913             break;
       
   914         default:
       
   915             DEBUG("Camera <> Unexpected orientation value");
       
   916             break;
       
   917         }
       
   918       }
       
   919     // Secondary camera rotations
       
   920     else if (aActiveCameraIndex == ECamActiveCameraSecondary)
       
   921     {
       
   922       if (aSensorOrientation == TSensrvOrientationData::EOrientationDisplayUp) // Portrait
       
   923       {
       
   924         DEBUG("CMMACameraPlayer::MapSensorOrientatio2CamOrientation Secondary-camera EOrientationDisplayUp");
       
   925         cameraOrientation = ECamOrientation180; 
       
   926       }
       
   927       else if (aSensorOrientation == TSensrvOrientationData::EOrientationDisplayDown)  // Upside down portrait
       
   928       {
       
   929         DEBUG("CMMACameraPlayer::MapSensorOrientatio2CamOrientation Secondary-camera EOrientationDisplayDown");
       
   930         cameraOrientation = ECamOrientation180;
       
   931       }
       
   932       else
       
   933       {
       
   934         DEBUG("CMMACameraPlayer::MapSensorOrientatio2CamOrientation Secondary-camera else");
       
   935         cameraOrientation = ECamOrientation0;
       
   936       }
       
   937     }
       
   938 
       
   939     return cameraOrientation;
       
   940 }
       
   941 
       
   942 MCameraOrientation::TOrientation CMMACameraPlayer::Map2CameraOrientation( 
       
   943     const TCamImageOrientation& aSettingOrientation )
       
   944 {
       
   945     DEBUG("CMMACameraPlayer::Map2CameraOrientation +");
       
   946     switch(aSettingOrientation)
       
   947     {
       
   948     case ECamOrientation90:
       
   949       DEBUG("CMMACameraPlayer::Map2CameraOrientation ECamOrientation90");
       
   950       return MCameraOrientation::EOrientation90;
       
   951     case ECamOrientation180:
       
   952       DEBUG("CMMACameraPlayer::Map2CameraOrientation ECamOrientation180");
       
   953       return MCameraOrientation::EOrientation180;
       
   954     case ECamOrientation270:
       
   955       DEBUG("CMMACameraPlayer::Map2CameraOrientation ECamOrientation270");
       
   956       return MCameraOrientation::EOrientation270;
       
   957     case ECamOrientation0:    // <<fall through>>
       
   958     default:                  
       
   959       DEBUG("CMMACameraPlayer::Map2CameraOrientation ECamOrientation0 or default");
       
   960       return MCameraOrientation::EOrientation0;
       
   961     }
       
   962 }
       
   963 
       
   964 //  END OF FILE