Tizen 2.1 base
[platform/framework/native/media.git] / src / FMedia_CameraCoordinator.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                        FMedia_CameraCoordinator.cpp
20  * @brief                       This file contains the implementation of the %FMedia_CameraCoordinator class.
21  *
22  */
23 #include <FBaseSysLog.h>
24 #include "FMedia_CameraManager.h"
25 #include "FMedia_RecorderManager.h"
26 #include "FMedia_CameraCoordinator.h"
27 #include "FMedia_ICameraCoordinatorListener.h"
28 #include "FMedia_CameraUtil.h"
29 #include "FMedia_RecorderUtil.h"
30
31 //#define _VIDEO_RECORDER_ROTATION_
32
33 using namespace Tizen::Base;
34 using namespace Tizen::Base::Collection;
35
36 namespace Tizen { namespace Media
37 {
38 static const int _ORIENTATION_FOR_RECORDING = 0x1;
39 static const int _ORIENTATION_FOR_CAMERA = 0x1 << 1;
40
41 typedef int (*_CameraFunc)(_CameraHandle mmHandle);
42
43 typedef struct
44 {
45         camera_state_e prevState;
46         camera_state_e postState;
47         _CameraFunc pFunc;
48 }_CameraStateTransitTable;
49
50 static const _CameraStateTransitTable _CAMERA_STATE_TRANSIT[] =
51 {
52         {::CAMERA_STATE_CREATED, ::CAMERA_STATE_PREVIEW, camera_start_preview },
53         {::CAMERA_STATE_CAPTURED, ::CAMERA_STATE_PREVIEW, camera_start_preview },
54         {::CAMERA_STATE_CAPTURED, ::CAMERA_STATE_CREATED, camera_stop_preview },
55         {::CAMERA_STATE_PREVIEW, ::CAMERA_STATE_CREATED, camera_stop_preview },
56 };
57
58 typedef int (*_RecorderFunc)(_RecorderHandle mmHandle);
59
60 typedef struct
61 {
62         recorder_state_e prevState;
63         recorder_state_e postState;
64         _RecorderFunc pFunc;
65 }_RecorderStateTransitTable;
66
67 static const _RecorderStateTransitTable _RECORDER_STATE_TRANSIT[] =
68 {
69         {::RECORDER_STATE_CREATED, ::RECORDER_STATE_READY, recorder_prepare },
70         {::RECORDER_STATE_READY, ::RECORDER_STATE_RECORDING, recorder_start },
71         {::RECORDER_STATE_RECORDING, ::RECORDER_STATE_PAUSED, recorder_pause },
72         {::RECORDER_STATE_RECORDING, ::RECORDER_STATE_READY, recorder_commit },
73 //      {::RECORDER_STATE_RECORDING, ::RECORDER_STATE_READY, recorder_cancel },
74         {::RECORDER_STATE_PAUSED, ::RECORDER_STATE_READY, recorder_commit },
75         {::RECORDER_STATE_PAUSED, ::RECORDER_STATE_READY, recorder_cancel },
76         {::RECORDER_STATE_READY, ::RECORDER_STATE_CREATED, recorder_unprepare },
77 };
78
79 _CameraCoordinatorSafeHashMapT* _CameraCoordinator::__pMap = null;
80
81 _CameraCoordinatorSafeHashMapT::_CameraCoordinatorSafeHashMapT(void)
82 {
83 }
84
85 _CameraCoordinatorSafeHashMapT::~_CameraCoordinatorSafeHashMapT(void)
86 {
87         RemoveItems();
88         _CameraCoordinator::__pMap = null;
89 }
90
91 void
92 _CameraCoordinatorSafeHashMapT::RemoveItems(void)
93 {
94         IListT <_CameraDeviceType>* pList = null;
95         _CameraCoordinator* pCoordinator = null;
96         result r = E_SUCCESS;
97
98         pList = GetKeysN();
99         SysTryReturn(NID_MEDIA, pList != null, , E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] There is no instance.");
100         for (int i = 0; i < GetCount(); i++)
101         {
102                 _CameraDeviceType deviceType = _CAMERA_DEVICE_NONE;
103                 r = pList->GetAt(i, deviceType);
104                 if (IsFailed(r) && deviceType == _CAMERA_DEVICE_NONE)
105                 {
106                         continue;
107                 }
108
109                 r = GetValue(deviceType, pCoordinator);
110                 if (IsFailed(r) && pCoordinator == null)
111                 {
112                         continue;
113                 }
114                 delete pCoordinator;
115         }
116         pList->RemoveAll();
117         delete pList;
118         RemoveAll();
119 }
120
121 _CameraCoordinator::_CameraCoordinator()
122         : __cameraDevice(_CAMERA_DEVICE_NONE)
123         , __cameraHandle(MM_INVALID_HANDLE)
124         , __recorderHandle(MM_INVALID_HANDLE)
125         , __mode(_CAMERA_MODE_NONE)
126         , __pListenerList(null)
127         , __orientationFlag(0)
128         , __cameraOrientation(CAMERA_EXIF_ORIENTATION_TOP_LEFT)
129         , __recordingRotation(RECORDING_ROTATION_NONE)
130 {
131 }
132
133 _CameraCoordinator::~_CameraCoordinator()
134 {
135         if (__pListenerList != null)
136         {
137                 __pListenerList->RemoveAll();
138                 delete __pListenerList;
139         }
140
141         _CameraManager::Release(__cameraDevice);
142         SysLog(NID_MEDIA, "Camera manager released");
143 }
144
145 result
146 _CameraCoordinator::Construct(_CameraDeviceType cameraDevice)
147 {
148         result r = E_SUCCESS;
149         _CameraManager* pCameraManager = null;
150         SysLog(NID_MEDIA, "Enter. camera device:%d", cameraDevice);
151
152         pCameraManager = _CameraManager::AddInstance(cameraDevice);
153         r = GetLastResult();
154         SysTryReturn(NID_MEDIA, pCameraManager !=null && r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
155
156         __cameraHandle = pCameraManager->GetHandle();
157
158         __pListenerList = new (std::nothrow) LinkedListT <_ICameraCoordinatorListener*>();
159         SysTryCatch(NID_MEDIA, __pListenerList !=null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.  The object is not created.");
160
161         __cameraDevice = cameraDevice;
162         __mode = _CAMERA_MODE_IMAGE;
163
164         return r;
165
166 CATCH:
167         return r;
168 }
169
170 result
171 _CameraCoordinator::AddRecorder(_RecorderDeviceType recorderDevice)
172 {
173         result r = E_SUCCESS;
174         _RecorderManager* pRecorderManager = null;
175         SysLog(NID_MEDIA, "Enter. recorder device:%d", recorderDevice);
176
177         pRecorderManager = _RecorderManager::AddInstance(recorderDevice);
178         r = GetLastResult();
179         SysTryCatch(NID_MEDIA, pRecorderManager !=null && r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
180
181         __recorderHandle = pRecorderManager->GetHandle();               // new recorder handle
182
183         return r;
184
185 CATCH:
186         return r;
187 }
188
189 void
190 _CameraCoordinator::RemoveRecorder(_RecorderDeviceType recorderDevice)
191 {
192         SysLog(NID_MEDIA, "Enter. recorder device:%d", recorderDevice);
193         _RecorderManager::Release(recorderDevice);
194         __recorderHandle = MM_INVALID_HANDLE;
195         __orientationFlag = __orientationFlag & (~_ORIENTATION_FOR_RECORDING);
196 }
197
198 _CameraCoordinator*
199 _CameraCoordinator::AddInstance(_CameraDeviceType cameraDevice)
200 {
201         result r = E_SUCCESS;
202         bool out = false;
203         ClearLastResult();
204
205         static bool isMapConstructed = false;
206         static _CameraCoordinatorSafeHashMapT map;
207         _CameraCoordinator* pCoordinator = null;
208
209         SysTryReturn(NID_MEDIA, cameraDevice > _CAMERA_DEVICE_NONE && cameraDevice < _CAMERA_DEVICE_MAX,
210                                 null, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument(camderDevice) is used. camderDevice:%d is wrong.", cameraDevice);
211
212         if (!isMapConstructed)
213         {
214                 r = map.Construct();
215                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
216                 isMapConstructed = true;
217                 __pMap = &map;
218         }
219
220         r = map.ContainsKey(cameraDevice, out);
221         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
222
223         if (out)
224         {
225                 r = map.GetValue(cameraDevice, pCoordinator);
226                 SysTryCatch(NID_MEDIA, r == E_SUCCESS && pCoordinator != null, , r, "[%s] Propagating.", GetErrorMessage(r));
227         }
228         else
229         {
230                 pCoordinator = new (std::nothrow) _CameraCoordinator();
231                 SysTryCatch(NID_MEDIA, pCoordinator !=null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.  The object is not created.");
232
233                 r = pCoordinator->Construct(cameraDevice);
234                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
235
236                 r = map.Add(cameraDevice, pCoordinator);
237                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
238         }
239
240         pCoordinator->AddRefCount();
241         return pCoordinator;
242
243 CATCH:
244         if (pCoordinator != null)
245         {
246                 delete pCoordinator;
247         }
248         return null;
249 }
250
251 _CameraCoordinator*
252 _CameraCoordinator::AddInstance(_RecorderDeviceType recorderDevice)
253 {
254         _CameraCoordinator* pCoordinator = null;
255         _CameraDeviceType cameraDevice = _CAMERA_DEVICE_NONE;
256         ClearLastResult();
257
258         switch (recorderDevice)
259         {
260         case _RECORDER_DEVICE_VIDEO_PRIMARY_CAMERA:
261                 cameraDevice = _CAMERA_DEVICE_PRIMARY;
262                 break;
263
264         case _RECORDER_DEVICE_VIDEO_SECONDARY_CAMERA:
265                 cameraDevice = _CAMERA_DEVICE_SECONDARY;
266                 break;
267
268         default:
269                 break;
270         }
271
272         if (cameraDevice == _CAMERA_DEVICE_NONE)
273         {
274                 SysLogException(NID_MEDIA, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument(recorderDevice) is used. recorderDevice :%d is wrong.", recorderDevice);
275         }
276         else
277         {
278                 pCoordinator = AddInstance(cameraDevice);
279                 if (pCoordinator == null)
280                 {
281                         SysLogException(NID_MEDIA, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] The camera device(%d)'s coordinator is not available.", cameraDevice);
282                 }
283         }
284         return pCoordinator;
285 }
286
287 void
288 _CameraCoordinator::Release(_CameraDeviceType cameraDevice)
289 {
290         result r = E_SUCCESS;
291
292         if (__pMap != null)
293         {
294                 _CameraCoordinator* pCoordinator = null;
295                 r = __pMap->GetValue(cameraDevice, pCoordinator);
296                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
297
298                 if (pCoordinator->ReleaseRefCount() == 0)
299                 {
300                         delete pCoordinator;
301                         r = __pMap->Remove(cameraDevice);
302                         SysTryReturn(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
303                 }
304         }
305 }
306
307 void
308 _CameraCoordinator::Release(_RecorderDeviceType recorderDevice)
309 {
310         if (__pMap != null)
311         {
312                 _CameraDeviceType cameraDevice = _CAMERA_DEVICE_NONE;
313
314                 switch (recorderDevice)
315                 {
316                 case _RECORDER_DEVICE_VIDEO_PRIMARY_CAMERA:
317                         cameraDevice = _CAMERA_DEVICE_PRIMARY;
318                         break;
319                 case _RECORDER_DEVICE_VIDEO_SECONDARY_CAMERA:
320                         cameraDevice = _CAMERA_DEVICE_SECONDARY;
321                         break;
322                 default:
323                         break;
324                 }
325
326                 Release(cameraDevice);
327         }
328 }
329
330 _CameraCoordinator*
331 _CameraCoordinator::HasInstance(_CameraDeviceType cameraDevice)
332 {
333         result r = E_SUCCESS;
334         _CameraCoordinator* pCoordinator = null;
335         bool out = false;
336         ClearLastResult();
337
338         SysTryReturn(NID_MEDIA, cameraDevice > _CAMERA_DEVICE_NONE && cameraDevice < _CAMERA_DEVICE_MAX,
339                                 null, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument(camderDevice) is used. camderDevice:%d is wrong.", cameraDevice);
340         SysTryReturn(NID_MEDIA, __pMap != null, null, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] No coordinator was created.");
341
342         r = __pMap->ContainsKey(cameraDevice, out);
343         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
344         SysTryCatch(NID_MEDIA, out == true, r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] Camera device(%d) was not created.", cameraDevice);
345
346         r = __pMap->GetValue(cameraDevice, pCoordinator);
347         SysTryCatch(NID_MEDIA, r == E_SUCCESS && pCoordinator != null, , r, "[%s] Propagating.", GetErrorMessage(r));
348
349         return pCoordinator;
350
351 CATCH:
352         return null;
353 }
354
355 _CameraCoordinator*
356 _CameraCoordinator::HasInstance(_RecorderDeviceType recorderDevice)
357 {
358         _CameraCoordinator* pCoordinator = null;
359         _CameraDeviceType cameraDevice = _CAMERA_DEVICE_NONE;
360         ClearLastResult();
361
362         switch (recorderDevice)
363         {
364         case _RECORDER_DEVICE_VIDEO_PRIMARY_CAMERA:
365                 cameraDevice = _CAMERA_DEVICE_PRIMARY;
366                 break;
367
368         case _RECORDER_DEVICE_VIDEO_SECONDARY_CAMERA:
369                 cameraDevice = _CAMERA_DEVICE_SECONDARY;
370                 break;
371
372         default:
373                 break;
374         }
375
376         if (cameraDevice == _CAMERA_DEVICE_NONE)
377         {
378                 SysLogException(NID_MEDIA, E_INVALID_ARG, "[E_INVALID_ARG] Invalid argument(recorderDevice) is used. recorderDevice :%d is wrong.", recorderDevice);
379         }
380         else
381         {
382                 pCoordinator = HasInstance(cameraDevice);
383                 if (pCoordinator == null)
384                 {
385                         SysLogException(NID_MEDIA, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] The camera device(%d)'s coordinator is not available.", cameraDevice);
386                 }
387         }
388         return pCoordinator;
389 }
390
391 result
392 _CameraCoordinator::AddCameraCoordinatorListener(_ICameraCoordinatorListener& listener)
393 {
394         result r = E_SUCCESS;
395         r = __pListenerList->Add(&listener);
396         return r;
397 }
398
399 result
400 _CameraCoordinator::RemoveCameraCoordinatorListener(_ICameraCoordinatorListener& listener)
401 {
402         result r = E_SUCCESS;
403         r = __pListenerList->Remove(&listener);
404         return r;
405 }
406
407 _CameraMode
408 _CameraCoordinator::GetMode(void) const
409 {
410         return __mode;
411 }
412
413 _CameraHandle
414 _CameraCoordinator::GetCameraHandle(void) const
415 {
416         return __cameraHandle;
417 }
418
419 _RecorderHandle
420 _CameraCoordinator::GetRecorderHandle(void) const
421 {
422         return __recorderHandle;
423 }
424
425 result
426 _CameraCoordinator::NotifyModeChangePrepared(_CameraMode mode)
427 {
428         result r = E_SUCCESS;
429         IEnumeratorT <_ICameraCoordinatorListener*>* pEnum = null;
430         _ICameraCoordinatorListener* pListener = null;
431         SysLog(NID_MEDIA, "mode:%d", mode);
432
433         pEnum = __pListenerList->GetEnumeratorN();
434         r = GetLastResult();
435         SysTryCatch(NID_MEDIA, pEnum != null, , r, "[%s] Propagating.", GetErrorMessage(r));
436
437         while (pEnum->MoveNext() == E_SUCCESS)
438         {
439                 r = pEnum->GetCurrent(pListener);
440                 SysTryCatch(NID_MEDIA, pListener != null && r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM,
441                                    "[E_SYSTEM] A system error has been occurred.  The listener is not proper");
442
443                 r = pListener->OnCameraCoordinatorModeChangePrepared(mode);
444                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
445         }
446
447         delete pEnum;
448         return r;
449
450 CATCH:
451         if (pEnum != null)
452         {
453                 delete pEnum;
454                 pEnum = null;
455         }
456         return r;
457 }
458
459 result
460 _CameraCoordinator::NotifyModeChanged(_CameraMode mode)
461 {
462         result r = E_SUCCESS;
463         IEnumeratorT <_ICameraCoordinatorListener*>* pEnum = null;
464         _ICameraCoordinatorListener* pListener = null;
465         SysLog(NID_MEDIA, "mode:%d", mode);
466
467         pEnum = __pListenerList->GetEnumeratorN();
468         r = GetLastResult();
469         SysTryCatch(NID_MEDIA, pEnum != null, , r, "[%s] Propagating.", GetErrorMessage(r));
470
471         while (pEnum->MoveNext() == E_SUCCESS)
472         {
473                 r = pEnum->GetCurrent(pListener);
474                 SysTryCatch(NID_MEDIA, pListener != null && r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM,
475                                    "[E_SYSTEM] A system error has been occurred.  The listener is not proper");
476
477                 r = pListener->OnCameraCoordinatorModeChanged(mode);
478                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
479         }
480
481         delete pEnum;
482         return r;
483
484 CATCH:
485         if (pEnum != null)
486         {
487                 delete pEnum;
488                 pEnum = null;
489         }
490         return r;
491 }
492
493 result
494 _CameraCoordinator::StartMmPreview(void)
495 {
496         result r = E_SUCCESS;
497         SysLog(NID_MEDIA, "Enter. mode:%d", __mode);
498
499         switch (__mode)
500         {
501         case _CAMERA_MODE_IMAGE:
502                 r = ChangeCameraStateTo(::CAMERA_STATE_PREVIEW);
503                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
504                 break;
505
506         case _CAMERA_MODE_VIDEO:
507                 r = ChangeRecorderStateTo(::RECORDER_STATE_READY);
508                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
509                 break;
510
511         default:
512                 SysLogException(NID_MEDIA, E_INVALID_STATE, "[E_INVALID_STATE] Camera is in an invalid state. Camcorder mode :%d is wrong", __mode);
513                 goto CATCH;
514                 break;
515         }
516
517 CATCH:
518         return r;
519 }
520
521 result
522 _CameraCoordinator::StopMmPreview(void)
523 {
524         result r = E_SUCCESS;
525         SysLog(NID_MEDIA, "Enter.");
526
527         if (__mode == _CAMERA_MODE_IMAGE)
528         {
529                 r = ChangeCameraStateTo(::CAMERA_STATE_CREATED);
530                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
531         }
532         else if (__mode == _CAMERA_MODE_VIDEO)
533         {
534                 recorder_state_e recorderState = ::RECORDER_STATE_NONE;
535                 recorderState = GetRecorderState();
536
537                 switch (recorderState)
538                 {
539                 case ::RECORDER_STATE_RECORDING:
540                         r = ChangeRecorderStateTo(::RECORDER_STATE_READY);
541                         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
542
543                         r = ChangeRecorderStateTo(::RECORDER_STATE_CREATED);
544                         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
545                         break;
546
547                 case ::RECORDER_STATE_READY:
548                         r = ChangeRecorderStateTo(::RECORDER_STATE_CREATED);
549                         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
550                         break;
551
552                 default:
553                         r = E_INVALID_STATE;
554                         SysLogException(NID_MEDIA, E_INVALID_STATE, "[E_INVALID_STATE] recorderState is in an invalid state. recorderState:%d", recorderState);
555                         break;
556                 }
557         }
558         else
559         {
560                 r = E_INVALID_STATE;
561                 SysLogException(NID_MEDIA, E_INVALID_STATE, "[E_INVALID_STATE] CamcorderMode is in an invalid state. mode :%d", __mode);
562         }
563
564 CATCH:
565         return r;
566 }
567
568 result
569 _CameraCoordinator::ChangeMode(_CameraMode mode, bool callback)
570 {
571         result r = E_SUCCESS;
572         camera_state_e cameraState = ::CAMERA_STATE_NONE;
573         recorder_state_e recorderState = ::RECORDER_STATE_NONE;
574         _RecorderDeviceType recorderDevice = _RECORDER_DEVICE_NONE;
575         int err = MM_SUCCESS;
576
577         SysLog(NID_MEDIA, "Mode should be changed. mode:%d", mode);
578         if (mode == _CAMERA_MODE_VIDEO)
579         {
580                 cameraState = GetCameraState();
581
582                 switch (cameraState)
583                 {
584                 case ::CAMERA_STATE_CREATED:
585                         //fall through
586                 case ::CAMERA_STATE_NONE:
587                         break;
588
589                 case ::CAMERA_STATE_PREVIEW:
590                         //fall through
591                 case ::CAMERA_STATE_CAPTURED:
592                         r = ChangeCameraStateTo(::CAMERA_STATE_CREATED);
593                         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
594                         break;
595
596                 case ::CAMERA_STATE_CAPTURING:
597                         r = E_INVALID_STATE;
598                         SysLogException(NID_MEDIA, r, "[E_INVALID_STATE] cameraState(%d) is in an invalid state. While the camera is capturing, the mode cannot be changed.", cameraState);
599                         goto CATCH;
600                         break;
601
602                 default:
603                         break;
604                 }
605
606                 // Start recorder
607                 if ( __recorderHandle == MM_INVALID_HANDLE )
608                 {
609                         recorderDevice = __cameraDevice == _CAMERA_DEVICE_PRIMARY ?
610                                 _RECORDER_DEVICE_VIDEO_PRIMARY_CAMERA : _RECORDER_DEVICE_VIDEO_SECONDARY_CAMERA;
611                         r = AddRecorder(recorderDevice);                // recorder_create() will be called.
612                         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
613                         __mode = _CAMERA_MODE_VIDEO;
614                 }
615
616                 if (callback)
617                 {
618                         r = NotifyModeChangePrepared(mode);
619                         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
620                 }
621
622                 switch (cameraState)
623                 {
624                 case ::CAMERA_STATE_NONE:
625                         //fall through
626                 case ::CAMERA_STATE_CREATED:
627                         break;
628
629                 case ::CAMERA_STATE_PREVIEW:
630                         r = ChangeRecorderStateTo(::RECORDER_STATE_READY);
631                         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
632                         break;
633
634                 case ::CAMERA_STATE_CAPTURED:
635                 default:
636                         break;
637                 }
638         }
639         else if ( mode == _CAMERA_MODE_IMAGE )
640         {
641                 recorderState = GetRecorderState();
642
643                 // Stop the recorder
644                 switch (recorderState)
645                 {
646                 case ::RECORDER_STATE_NONE:
647                         break;
648
649                 case ::RECORDER_STATE_CREATED:
650                         recorderDevice = __cameraDevice == _CAMERA_DEVICE_PRIMARY ?
651                                 _RECORDER_DEVICE_VIDEO_PRIMARY_CAMERA : _RECORDER_DEVICE_VIDEO_SECONDARY_CAMERA;
652                         RemoveRecorder(recorderDevice);         // the mode will be changed to IMAGE.
653                         __mode = _CAMERA_MODE_IMAGE;
654                         break;
655
656                 case ::RECORDER_STATE_READY:
657                         r = ChangeRecorderStateTo(::RECORDER_STATE_CREATED);
658                         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
659
660                         recorderDevice = __cameraDevice == _CAMERA_DEVICE_PRIMARY ?
661                                 _RECORDER_DEVICE_VIDEO_PRIMARY_CAMERA : _RECORDER_DEVICE_VIDEO_SECONDARY_CAMERA;
662                         RemoveRecorder(recorderDevice);
663                         __mode = _CAMERA_MODE_IMAGE;
664                         if (callback)
665                         {
666                                 r = NotifyModeChangePrepared(mode);
667                                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
668                         }
669                         r = ChangeCameraStateTo(::CAMERA_STATE_PREVIEW);
670                         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
671                         break;
672
673                 case ::RECORDER_STATE_RECORDING:
674                         //fall through
675                 case ::RECORDER_STATE_PAUSED:
676                         err = recorder_cancel(__recorderHandle);                // TODO
677                         r = ConvertResult(err);
678                         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
679
680                         r = ChangeRecorderStateTo(::RECORDER_STATE_CREATED);
681                         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
682                         recorderDevice = __cameraDevice == _CAMERA_DEVICE_PRIMARY ?
683                                 _RECORDER_DEVICE_VIDEO_PRIMARY_CAMERA : _RECORDER_DEVICE_VIDEO_SECONDARY_CAMERA;
684
685                         RemoveRecorder(recorderDevice);
686                         __mode = _CAMERA_MODE_IMAGE;
687                         if (callback)
688                         {
689                                 r = NotifyModeChangePrepared(mode);
690                                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
691                         }
692                         r = ChangeCameraStateTo(::CAMERA_STATE_PREVIEW);
693                         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
694                         break;
695
696                 default:
697                         break;
698                 }
699         }
700
701         if (callback)
702         {
703                 // Notify that the mode is changed to callback camera and video recorder's configurations.
704                 r = NotifyModeChanged(mode);
705                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
706         }
707
708         return r;
709
710 CATCH:
711         return r;
712 }
713
714 bool
715 _CameraCoordinator::IsCalmChangeMode(_CameraMode mode)
716 {
717         camera_state_e cameraState = ::CAMERA_STATE_NONE;
718         recorder_state_e recorderState = ::RECORDER_STATE_NONE;
719         bool calmChange = false;
720
721         if (mode == _CAMERA_MODE_VIDEO)
722         {
723                 cameraState = GetCameraState();
724
725                 switch (cameraState)
726                 {
727                 case ::CAMERA_STATE_CREATED:
728                         //fall through
729                 case ::CAMERA_STATE_NONE:
730                         calmChange = true;
731                         break;
732
733                 case ::CAMERA_STATE_PREVIEW:
734                         //fall through
735                 case ::CAMERA_STATE_CAPTURED:
736                         //fall through
737                 case ::CAMERA_STATE_CAPTURING:
738                         calmChange = false;
739                         break;
740
741                 default:
742                         break;
743                 }
744         }
745         else if ( mode == _CAMERA_MODE_IMAGE )
746         {
747                 recorderState = GetRecorderState();
748
749                 // Stop the recorder
750                 switch (recorderState)
751                 {
752                 case ::RECORDER_STATE_NONE:
753                         //fall through
754                 case ::RECORDER_STATE_CREATED:
755                         calmChange = true;
756                         break;
757
758                 case ::RECORDER_STATE_READY:
759                         //fall through
760                 case ::RECORDER_STATE_RECORDING:
761                         //fall through
762                 case ::RECORDER_STATE_PAUSED:
763                         calmChange = false;
764                         break;
765
766                 default:
767                         break;
768                 }
769         }
770
771         SysLog(NID_MEDIA, "mode:%d, calm:%d", mode, calmChange);
772         return calmChange;
773 }
774
775
776 _CameraDeviceType
777 _CameraCoordinator::GetCameraDevice(void) const
778 {
779         return __cameraDevice;
780 }
781
782 camera_state_e
783 _CameraCoordinator::GetCameraState(void) const
784 {
785         result r = E_SUCCESS;
786         int err = MM_SUCCESS;
787         camera_state_e state = ::CAMERA_STATE_NONE;
788
789         err = camera_get_state(__cameraHandle, &state);
790         r = ConvertResult(err);
791         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
792
793         return state;
794
795 CATCH:
796         return ::CAMERA_STATE_NONE;
797 }
798
799 recorder_state_e
800 _CameraCoordinator::GetRecorderState(void) const
801 {
802         result r = E_SUCCESS;
803         int err = MM_SUCCESS;
804         recorder_state_e state = ::RECORDER_STATE_NONE;
805
806         err = recorder_get_state(__recorderHandle, &state);
807         r = ConvertResult(err);
808         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating.", GetErrorMessage(r));
809
810         return state;
811
812 CATCH:
813         return ::RECORDER_STATE_NONE;
814 }
815
816 result
817 _CameraCoordinator::ConvertResult(int err) const
818 {
819         result r = E_SYSTEM;
820         if (err != CAMERA_ERROR_NONE)
821         {
822                 SysLog(NID_MEDIA, "MM Err:0x%x", err);
823         }
824
825         // Global error
826         if (err == CAMERA_ERROR_NONE || err == RECORDER_ERROR_NONE)
827         {
828                 r = E_SUCCESS;
829         }
830         else if (err == CAMERA_ERROR_INVALID_PARAMETER || err == RECORDER_ERROR_INVALID_PARAMETER)
831         {
832                 r = E_INVALID_ARG;
833         }
834         else if (err == CAMERA_ERROR_INVALID_STATE || err == RECORDER_ERROR_INVALID_STATE)
835         {
836                 r = E_INVALID_STATE;
837         }
838         else if (err == CAMERA_ERROR_OUT_OF_MEMORY || err == RECORDER_ERROR_OUT_OF_MEMORY)
839         {
840                 r = E_OUT_OF_MEMORY;
841         }
842         else if (err == CAMERA_ERROR_DEVICE || err == RECORDER_ERROR_DEVICE)
843         {
844                 r = E_DEVICE_FAILED;
845         }
846         else if (err == CAMERA_ERROR_INVALID_OPERATION
847                         || err == CAMERA_ERROR_SECURITY_RESTRICTED
848                         || err == RECORDER_ERROR_INVALID_OPERATION
849                         || err == RECORDER_ERROR_SECURITY_RESTRICTED)
850         {
851                 r = E_SYSTEM;
852         }
853         else if (err == CAMERA_ERROR_DEVICE_BUSY
854                         || err == CAMERA_ERROR_SOUND_POLICY
855                         || err == RECORDER_ERROR_SOUND_POLICY)
856         {
857                 r = E_DEVICE_BUSY;
858         }
859         else if (err == CAMERA_ERROR_DEVICE_NOT_FOUND)
860         {
861                 r = E_DEVICE_UNAVAILABLE;
862         }
863         else
864         {
865                 r = E_UNKNOWN;
866         }
867
868         return r;
869 }
870
871
872 result
873 _CameraCoordinator::ChangeCameraStateTo(camera_state_e destState)
874 {
875         result r = E_SUCCESS;
876         int tableTotalCount = 0;
877         int i = 0;
878         int err = MM_SUCCESS;
879         camera_state_e preState = ::CAMERA_STATE_NONE;
880         camera_state_e postState = ::CAMERA_STATE_NONE;
881
882         preState = GetCameraState();
883         tableTotalCount = sizeof(_CAMERA_STATE_TRANSIT) / sizeof(_CAMERA_STATE_TRANSIT[0]);
884         SysLog(NID_MEDIA, " PreState:%d, destState:%d, tableTotalCount:%d", preState, destState, tableTotalCount);
885
886         for (i = 0; i < tableTotalCount; i++)
887         {
888                 if (preState == _CAMERA_STATE_TRANSIT[i].prevState && destState == _CAMERA_STATE_TRANSIT[i].postState)
889                 {
890                         if (_CAMERA_STATE_TRANSIT[i].pFunc != null)
891                         {
892                                 SysLog(NID_MEDIA,
893                                                         "Exist the matching state field. loop i:%d, current state:%d, destState:%d", i,
894                                                         preState, destState);
895                                 err = _CAMERA_STATE_TRANSIT[i].pFunc(__cameraHandle);
896                                 r = ConvertResult(err);
897                                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating. i:%d", GetErrorMessage(r), i);
898
899                                 // Check whether the retuned states are destinationed states.
900                                 postState = GetCameraState();
901                                 SysTryCatch(NID_MEDIA, destState == postState, r = E_INVALID_STATE, E_INVALID_STATE,
902                                                    "[E_INVALID_STATE] camera_state_e of C-API is in an invalid state. result preState:%d, is different from the desired state:%d", postState,
903                                                    destState);
904                                 SysLog(NID_MEDIA, "[E_SUCCESS] Found. result postState:%d, param destState:%d", postState,
905                                                         destState);
906                         }
907                         break;
908                 }
909
910         }
911         SysTryCatch(NID_MEDIA, i != tableTotalCount, r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Not found. ");
912         return r;
913
914 CATCH:
915         SysLog(NID_MEDIA, "[%s] Real preState:%d, param destState:%d", GetErrorMessage(r), preState, destState);
916         return r;
917 }
918
919 result
920 _CameraCoordinator::ChangeRecorderStateTo(recorder_state_e destState)
921 {
922         result r = E_SUCCESS;
923         int tableTotalCount = 0;
924         int i = 0;
925         int err = MM_SUCCESS;
926         recorder_state_e preState = ::RECORDER_STATE_NONE;
927         recorder_state_e postState = ::RECORDER_STATE_NONE;
928
929         preState = GetRecorderState();
930         tableTotalCount = sizeof(_RECORDER_STATE_TRANSIT) / sizeof(_RECORDER_STATE_TRANSIT[0]);
931         SysLog(NID_MEDIA, " PreState:%d, destState:%d, tableTotalCount:%d", preState, destState, tableTotalCount);
932
933         for (i = 0; i < tableTotalCount; i++)
934         {
935                 if (preState == _RECORDER_STATE_TRANSIT[i].prevState && destState == _RECORDER_STATE_TRANSIT[i].postState)
936                 {
937                         if (_RECORDER_STATE_TRANSIT[i].pFunc != null)
938                         {
939                                 SysLog(NID_MEDIA,
940                                                         "Exist the matching state field. loop i:%d, current state:%d, destState:%d", i,
941                                                         preState, destState);
942                                 err = _RECORDER_STATE_TRANSIT[i].pFunc(__recorderHandle);
943                                 r = ConvertResult(err);
944                                 SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating. i:%d", GetErrorMessage(r), i);
945
946                                 // Check whether the retuned states are destinationed states.
947                                 postState = GetRecorderState();
948                                 SysTryCatch(NID_MEDIA, destState == postState, r = E_INVALID_STATE, E_INVALID_STATE,
949                                                    "[E_INVALID_STATE] recorder_state_e of C-API is in an invalid state. result preState:%d, is different from the desired state:%d", postState,
950                                                    destState);
951                                 SysLog(NID_MEDIA, "[E_SUCCESS] Found. result preState:%d, param destState:%d", postState,
952                                                         destState);
953                         }
954                         break;
955                 }
956
957         }
958         SysTryCatch(NID_MEDIA, i != tableTotalCount, r = E_INVALID_STATE, E_INVALID_STATE, "[E_INVALID_STATE] Not found. ");
959         return r;
960
961 CATCH:
962         SysLog(NID_MEDIA, "[%s] Real preState:%d, param destState:%d", GetErrorMessage(r), preState, destState);
963         return r;
964 }
965
966 result
967 _CameraCoordinator::SetCameraSourceFormat(camera_pixel_format_e pixelFormat)
968 {
969         result r = E_SUCCESS;
970         int err = MM_SUCCESS;
971         SysLog(NID_MEDIA, "Camera_pixel_format_e is :%d", pixelFormat);
972
973         err = camera_set_preview_format(__cameraHandle, pixelFormat);
974         r = ConvertResult(err);
975         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating, pixelFormat:%d", GetErrorMessage(r), pixelFormat);
976
977         return r;
978
979 CATCH:
980         return r;
981 }
982
983 camera_pixel_format_e
984 _CameraCoordinator::GetCameraSourceFormat(void) const
985 {
986         result r = E_SUCCESS;
987         int err = MM_SUCCESS;
988         camera_pixel_format_e pixelFormat = CAMERA_PIXEL_FORMAT_INVALID;
989
990         err = camera_get_preview_format(__cameraHandle, &pixelFormat);
991         r = ConvertResult(err);
992         SysTryCatch(NID_MEDIA, r == E_SUCCESS, , r, "[%s] Propagating", GetErrorMessage(r));
993
994         return pixelFormat;
995
996 CATCH:
997         return pixelFormat;
998 }
999
1000 result
1001 _CameraCoordinator::StartCapture(camera_capturing_cb capturingCb , camera_capture_completed_cb completedCb , void *pUserData)
1002 {
1003         result r = E_SUCCESS;
1004         int err = MM_SUCCESS;
1005
1006         if (__orientationFlag & _ORIENTATION_FOR_CAMERA)
1007         {
1008                 r = SetCameraOrientationAttr(__cameraOrientation);
1009                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1010         }
1011         else if (__orientationFlag & _ORIENTATION_FOR_RECORDING)        // If recorder setting is remained.
1012         {
1013                 r = SetCameraOrientationAttr(CAMERA_EXIF_ORIENTATION_TOP_LEFT); // To set the init value
1014                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1015         }
1016
1017         err = camera_start_capture(__cameraHandle, capturingCb, completedCb, pUserData);
1018         r = ConvertResult(err);
1019         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Camera capture failed.", GetErrorMessage(r));
1020
1021         return r;
1022 }
1023
1024 result
1025 _CameraCoordinator::StartRecord(void)
1026 {
1027         result r = E_SUCCESS;
1028         int err = MM_SUCCESS;
1029
1030         if (__orientationFlag & _ORIENTATION_FOR_RECORDING)
1031         {
1032                 r = SetRecordingOrientationAttr(__recordingRotation);
1033                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1034         }
1035         else if (__orientationFlag & _ORIENTATION_FOR_CAMERA)   // If recorder setting is remained.
1036         {
1037                 r = SetRecordingOrientationAttr(RECORDING_ROTATION_NONE);       // To set the init value
1038                 SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
1039         }
1040
1041         err = recorder_start(__recorderHandle);
1042         r = ConvertResult(err);
1043         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Recorder record failed.", GetErrorMessage(r));
1044
1045         return r;
1046 }
1047
1048 void
1049 _CameraCoordinator::SetRecordingOrientation(RecordingRotation rotation)
1050 {
1051         __orientationFlag = __orientationFlag | _ORIENTATION_FOR_RECORDING;
1052         __recordingRotation = rotation;
1053 }
1054
1055 void
1056 _CameraCoordinator::SetCameraOrientation(CameraExifOrientation orientation)
1057 {
1058         __orientationFlag = __orientationFlag | _ORIENTATION_FOR_CAMERA;
1059         __cameraOrientation = orientation;
1060 }
1061
1062 result
1063 _CameraCoordinator::SetRecordingOrientationAttr(RecordingRotation rotation)
1064 {
1065         result r = E_SUCCESS;
1066         int err = MM_SUCCESS;
1067 #if _VIDEO_RECORDER_ROTATION_
1068         recorder_rotation_e mmAttr = ::RECORDER_ROTATION_NONE;
1069         r = _RecorderUtil::GetMmRotation(rotation, mmAttr);
1070         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating. rotation:%d", GetErrorMessage(r), rotation);
1071
1072         err = recorder_attr_set_recording_orientation(__recorderHandle, mmAttr);
1073         r = ConvertResult(err);
1074         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Camcorder set attribute failed. rotation:%d", GetErrorMessage(r), rotation);
1075 #else
1076         CameraRotation cameraRotation = CAMERA_ROTATION_NONE;
1077         r = _RecorderUtil::GetCameraRotation(rotation, cameraRotation);
1078         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating. rotation:%d", GetErrorMessage(r), rotation);
1079
1080         camera_attr_tag_orientation_e mmOrientationAttr = CAMERA_ATTR_TAG_ORIENTATION_TOP_LEFT;
1081         r = _CameraUtil::GetMmExifOrientation(cameraRotation, mmOrientationAttr);
1082         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating. rotation:%d", GetErrorMessage(r), rotation);
1083
1084         err = camera_attr_set_tag_orientation(__cameraHandle, mmOrientationAttr);
1085         r = ConvertResult(err);
1086         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Camcorder set attribute failed. Mm orientation:%d", GetErrorMessage(r), mmOrientationAttr);
1087 #endif
1088
1089         return r;
1090 }
1091
1092 result
1093 _CameraCoordinator::SetCameraOrientationAttr(CameraExifOrientation orientation)
1094 {
1095         result r = E_SUCCESS;
1096         int err = MM_SUCCESS;
1097         camera_attr_tag_orientation_e attr = ::CAMERA_ATTR_TAG_ORIENTATION_TOP_LEFT;
1098
1099         r = _CameraUtil::GetMmExifOrientation(orientation, attr);
1100         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating. orientation:%d", GetErrorMessage(r), orientation);
1101
1102         err = camera_attr_set_tag_orientation(__cameraHandle, attr);
1103         r = ConvertResult(err);
1104         SysTryReturn(NID_MEDIA, r == E_SUCCESS, r, r, "[%s] Propagating. orientation:%d", GetErrorMessage(r), orientation);
1105
1106         return r;
1107 }
1108
1109 }}