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