|
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 |