tizen 2.4 release
[framework/multimedia/libmm-camcorder.git] / src / mm_camcorder_internal.c
1 /*
2  * libmm-camcorder
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jeongmo Yang <jm80.yang@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 /*=======================================================================================
23 |  INCLUDE FILES                                                                        |
24 ========================================================================================*/
25 #include <stdio.h>
26 #include <string.h>
27 #include <fcntl.h>
28 #include <gst/gst.h>
29 #include <gst/gstutils.h>
30 #include <gst/gstpad.h>
31 #include <sys/time.h>
32
33 #include <mm_error.h>
34 #include "mm_camcorder_internal.h"
35 #include <mm_types.h>
36
37 #include <gst/video/colorbalance.h>
38 #include <gst/video/cameracontrol.h>
39 #include <asm/types.h>
40
41 #include <mm_session.h>
42 #include <mm_session_private.h>
43 #include <audio-session-manager.h>
44
45 #include <system_info.h>
46
47 /*---------------------------------------------------------------------------------------
48 |    GLOBAL VARIABLE DEFINITIONS for internal                                           |
49 ---------------------------------------------------------------------------------------*/
50 int g_mm_camcorder_type = -255;
51 struct sigaction mm_camcorder_int_old_action;
52 struct sigaction mm_camcorder_abrt_old_action;
53 struct sigaction mm_camcorder_segv_old_action;
54 struct sigaction mm_camcorder_term_old_action;
55 struct sigaction mm_camcorder_sys_old_action;
56
57 /*---------------------------------------------------------------------------------------
58 |    LOCAL VARIABLE DEFINITIONS for internal                                            |
59 ---------------------------------------------------------------------------------------*/
60 #define __MMCAMCORDER_CMD_ITERATE_MAX           3
61 #define __MMCAMCORDER_SET_GST_STATE_TIMEOUT     3
62 #define __MMCAMCORDER_FORCE_STOP_TRY_COUNT      30
63 #define __MMCAMCORDER_FORCE_STOP_WAIT_TIME      100000  /* us */
64 #define __MMCAMCORDER_SOUND_WAIT_TIMEOUT        3
65 #define __MMCAMCORDER_PATH_CAMERA_RESOURCE      "/usr/share/sounds/mm-camcorder/camera_resource"
66 #define __MMCAMCORDER_PATH_RECORDER_RESOURCE    "/usr/share/sounds/mm-camcorder/recorder_resource"
67
68
69 /*---------------------------------------------------------------------------------------
70 |    LOCAL FUNCTION PROTOTYPES:                                                         |
71 ---------------------------------------------------------------------------------------*/
72 /* STATIC INTERNAL FUNCTION */
73 static gboolean __mmcamcorder_gstreamer_init(camera_conf * conf);
74
75 static gboolean __mmcamcorder_handle_gst_error(MMHandleType handle, GstMessage *message, GError *error);
76 static gint     __mmcamcorder_gst_handle_stream_error(MMHandleType handle, int code, GstMessage *message);
77 static gint     __mmcamcorder_gst_handle_resource_error(MMHandleType handle, int code, GstMessage *message);
78 static gint     __mmcamcorder_gst_handle_library_error(MMHandleType handle, int code, GstMessage *message);
79 static gint     __mmcamcorder_gst_handle_core_error(MMHandleType handle, int code, GstMessage *message);
80 static gint     __mmcamcorder_gst_handle_resource_warning(MMHandleType handle, GstMessage *message , GError *error);
81 static gboolean __mmcamcorder_handle_gst_warning(MMHandleType handle, GstMessage *message, GError *error);
82
83 static void     __mmcamcorder_force_stop(mmf_camcorder_t *hcamcorder);
84 static void     __mmcamcorder_force_resume(mmf_camcorder_t *hcamcorder);
85 ASM_cb_result_t _mmcamcorder_asm_callback(int handle, ASM_event_sources_t event_src,
86                                           ASM_sound_commands_t command,
87                                           unsigned int sound_status, void *cb_data);
88
89 #ifdef _MMCAMCORDER_USE_SET_ATTR_CB
90 static gboolean __mmcamcorder_set_attr_to_camsensor_cb(gpointer data);
91 #endif /* _MMCAMCORDER_USE_SET_ATTR_CB */
92
93 static void __mm_camcorder_signal_handler(int signo);
94 static void _mmcamcorder_constructor() __attribute__((constructor));
95
96 /*=======================================================================================
97 |  FUNCTION DEFINITIONS                                                                 |
98 =======================================================================================*/
99 /*---------------------------------------------------------------------------------------
100 |    GLOBAL FUNCTION DEFINITIONS:                                                       |
101 ---------------------------------------------------------------------------------------*/
102
103 static void __mm_camcorder_signal_handler(int signo)
104 {
105         pid_t my_pid = getpid();
106         pid_t vconf_recorder_pid = -1;
107         pid_t vconf_camera_pid = -1;
108         int vconf_flash_state = VCONFKEY_CAMERA_FLASH_STATE_OFF;
109
110         _mmcam_dbg_warn("start - signo [%d], pid [%d], device type [%d]", signo, my_pid, g_mm_camcorder_type);
111
112         /* reset vconf key */
113         switch (g_mm_camcorder_type) {
114         case MM_VIDEO_DEVICE_NONE:
115                 vconf_get_int(VCONFKEY_RECORDER_PID, (int *)&vconf_recorder_pid);
116                 if (my_pid == vconf_recorder_pid) {
117                         vconf_set_int(VCONFKEY_RECORDER_STATE, VCONFKEY_RECORDER_STATE_NULL);
118                         vconf_set_int(VCONFKEY_RECORDER_PID, -1);
119                         _mmcam_dbg_warn("set recorder state NULL");
120                 } else {
121                         _mmcam_dbg_warn("different pid : my[%d] vconf[%d]", my_pid, vconf_recorder_pid);
122                 }
123                 break;
124         case MM_VIDEO_DEVICE_CAMERA0:
125         case MM_VIDEO_DEVICE_CAMERA1:
126                 vconf_get_int(VCONFKEY_CAMERA_FLASH_STATE, &vconf_flash_state);
127                 vconf_get_int(VCONFKEY_CAMERA_PID, (int *)&vconf_camera_pid);
128                 if (my_pid == vconf_camera_pid &&
129                         vconf_flash_state == VCONFKEY_CAMERA_FLASH_STATE_ON) {
130                         vconf_set_int(VCONFKEY_CAMERA_FLASH_STATE, VCONFKEY_CAMERA_FLASH_STATE_OFF);
131                         vconf_set_int(VCONFKEY_CAMERA_PID, -1);
132                         _mmcam_dbg_warn("set camera flash state OFF");
133                 }
134
135                 vconf_set_int(VCONFKEY_CAMERA_STATE, VCONFKEY_CAMERA_STATE_NULL);
136                 _mmcam_dbg_warn("set camera state NULL");
137                 break;
138         default:
139                 _mmcam_dbg_warn("unknown type [%d]", g_mm_camcorder_type);
140                 break;
141         }
142
143         /* call old signal handler */
144         switch (signo) {
145         case SIGINT:
146                 sigaction(SIGINT, &mm_camcorder_int_old_action, NULL);
147                 raise(signo);
148                 break;
149         case SIGABRT:
150                 sigaction(SIGABRT, &mm_camcorder_abrt_old_action, NULL);
151                 raise(signo);
152                 break;
153         case SIGSEGV:
154                 sigaction(SIGSEGV, &mm_camcorder_segv_old_action, NULL);
155                 raise(signo);
156                 break;
157         case SIGTERM:
158                 sigaction(SIGTERM, &mm_camcorder_term_old_action, NULL);
159                 raise(signo);
160                 break;
161         case SIGSYS:
162                 sigaction(SIGSYS, &mm_camcorder_sys_old_action, NULL);
163                 raise(signo);
164                 break;
165         default:
166                 break;
167         }
168
169         _mmcam_dbg_warn("done");
170
171         return;
172 }
173
174
175 static void _mmcamcorder_constructor()
176 {
177         struct sigaction mm_camcorder_action;
178         mm_camcorder_action.sa_handler = __mm_camcorder_signal_handler;
179         mm_camcorder_action.sa_flags = SA_NOCLDSTOP;
180
181         _mmcam_dbg_warn("start");
182
183         sigemptyset(&mm_camcorder_action.sa_mask);
184
185         sigaction(SIGINT, &mm_camcorder_action, &mm_camcorder_int_old_action);
186         sigaction(SIGABRT, &mm_camcorder_action, &mm_camcorder_abrt_old_action);
187         sigaction(SIGSEGV, &mm_camcorder_action, &mm_camcorder_segv_old_action);
188         sigaction(SIGTERM, &mm_camcorder_action, &mm_camcorder_term_old_action);
189         sigaction(SIGSYS, &mm_camcorder_action, &mm_camcorder_sys_old_action);
190
191         _mmcam_dbg_warn("done");
192
193         return;
194 }
195
196
197 /* Internal command functions {*/
198 int _mmcamcorder_create(MMHandleType *handle, MMCamPreset *info)
199 {
200         int ret = MM_ERROR_NONE;
201         int UseConfCtrl = 0;
202         int errorcode = MM_ERROR_NONE;
203         int rcmd_fmt_capture = MM_PIXEL_FORMAT_YUYV;
204         int rcmd_fmt_recording = MM_PIXEL_FORMAT_NV12;
205         int rcmd_dpy_rotation = MM_DISPLAY_ROTATION_270;
206         int play_capture_sound = TRUE;
207         int camera_device_count = MM_VIDEO_DEVICE_NUM;
208         int camera_default_flip = MM_FLIP_NONE;
209         int camera_facing_direction = MM_CAMCORDER_CAMERA_FACING_DIRECTION_REAR;
210         int resource_fd = -1;
211         char *err_attr_name = NULL;
212         const char *ConfCtrlFile = NULL;
213         mmf_camcorder_t *hcamcorder = NULL;
214         ASM_resource_t mm_resource = ASM_RESOURCE_NONE;
215         type_element *EvasSurfaceElement = NULL;
216         char err_msg[MAX_ERROR_MESSAGE_LEN] = {'\0',};
217
218         _mmcam_dbg_log("Entered");
219
220         mmf_return_val_if_fail(handle, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
221         mmf_return_val_if_fail(info, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
222
223         /* Create mmf_camcorder_t handle and initialize every variable */
224         hcamcorder = (mmf_camcorder_t *)malloc(sizeof(mmf_camcorder_t));
225         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_LOW_MEMORY);
226         memset(hcamcorder, 0x00, sizeof(mmf_camcorder_t));
227
228         /* init values */
229         hcamcorder->type = 0;
230         hcamcorder->state = MM_CAMCORDER_STATE_NONE;
231         hcamcorder->sub_context = NULL;
232         hcamcorder->target_state = MM_CAMCORDER_STATE_NULL;
233         hcamcorder->capture_in_recording = FALSE;
234         hcamcorder->asm_session_type = MM_SESSION_TYPE_RECORD_VIDEO;
235         hcamcorder->asm_handle = -1;
236
237         pthread_mutex_init(&((hcamcorder->mtsafe).lock), NULL);
238         pthread_cond_init(&((hcamcorder->mtsafe).cond), NULL);
239         pthread_mutex_init(&((hcamcorder->mtsafe).cmd_lock), NULL);
240         pthread_cond_init(&((hcamcorder->mtsafe).cmd_cond), NULL);
241         pthread_mutex_init(&((hcamcorder->mtsafe).asm_lock), NULL);
242         pthread_mutex_init(&((hcamcorder->mtsafe).state_lock), NULL);
243         pthread_mutex_init(&((hcamcorder->mtsafe).gst_state_lock), NULL);
244         pthread_mutex_init(&((hcamcorder->mtsafe).gst_encode_state_lock), NULL);
245         pthread_mutex_init(&((hcamcorder->mtsafe).message_cb_lock), NULL);
246         pthread_mutex_init(&((hcamcorder->mtsafe).vcapture_cb_lock), NULL);
247         pthread_mutex_init(&((hcamcorder->mtsafe).vstream_cb_lock), NULL);
248         pthread_mutex_init(&((hcamcorder->mtsafe).astream_cb_lock), NULL);
249
250         pthread_mutex_init(&(hcamcorder->sound_lock), NULL);
251         pthread_cond_init(&(hcamcorder->sound_cond), NULL);
252         pthread_mutex_init(&(hcamcorder->restart_preview_lock), NULL);
253
254         /* Sound mutex/cond init */
255         pthread_mutex_init(&(hcamcorder->snd_info.open_mutex), NULL);
256         pthread_cond_init(&(hcamcorder->snd_info.open_cond), NULL);
257
258         /* init for sound thread */
259         pthread_mutex_init(&(hcamcorder->task_thread_lock), NULL);
260         pthread_cond_init(&(hcamcorder->task_thread_cond), NULL);
261         hcamcorder->task_thread_state = _MMCAMCORDER_SOUND_STATE_NONE;
262
263         /* create task thread */
264         pthread_create(&(hcamcorder->task_thread), NULL, _mmcamcorder_task_thread_func, (void *)hcamcorder);
265
266         /* get root directory */
267         ret = _mmcamcorder_get_root_directory(&hcamcorder->root_directory);
268         if (ret != MM_ERROR_NONE) {
269                 goto _ERR_DEFAULT_VALUE_INIT;
270         }
271
272         if (info->videodev_type < MM_VIDEO_DEVICE_NONE ||
273             info->videodev_type >= MM_VIDEO_DEVICE_NUM) {
274                 _mmcam_dbg_err("_mmcamcorder_create::video device type is out of range.");
275                 ret = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
276                 goto _ERR_DEFAULT_VALUE_INIT;
277         }
278
279         /* set device type */
280         hcamcorder->device_type = info->videodev_type;
281         _mmcam_dbg_warn("Device Type : %d", hcamcorder->device_type);
282
283         if (hcamcorder->device_type == MM_VIDEO_DEVICE_NONE) {
284                 resource_fd = open(__MMCAMCORDER_PATH_RECORDER_RESOURCE, O_RDONLY);
285         } else {
286                 resource_fd = open(__MMCAMCORDER_PATH_CAMERA_RESOURCE, O_RDONLY);
287         }
288
289         if (resource_fd < 0) {
290                 strerror_r(errno, err_msg, MAX_ERROR_MESSAGE_LEN);
291                 _mmcam_dbg_log("open error %s : cur %d",err_msg,errno);
292                 if(errno == EPERM || errno == EACCES) {
293                         ret = MM_ERROR_COMMON_INVALID_PERMISSION;
294                 } else {
295                         ret = MM_ERROR_CAMCORDER_INTERNAL;
296                 }
297                 goto _ERR_DEFAULT_VALUE_INIT;
298         } else {
299                 close(resource_fd);
300                 resource_fd = -1;
301                 _mmcam_dbg_warn("permission check done");
302         }
303
304         /* Check and register ASM */
305         if (MM_ERROR_NONE != _mm_session_util_read_information(-1, &hcamcorder->asm_session_type, &hcamcorder->asm_session_options)) {
306                 _mmcam_dbg_log("_mm_session_util_read_information failed. use default session..");
307                 ret = _mm_session_util_write_type(-1, MM_SESSION_TYPE_MEDIA);
308                 if (ret) {
309                         _mmcam_dbg_err("mm_session_util_write_type() [type %d] failed[%x]", MM_SESSION_TYPE_MEDIA, ret);
310                         goto _ERR_DEFAULT_VALUE_INIT;
311                 } else {
312                         /* register default type */
313                         hcamcorder->asm_session_type = MM_SESSION_TYPE_MEDIA;
314                         hcamcorder->asm_register = _MMCamcorder_ASM_SESSION_REGISTERED_INTERNALLY;
315                         hcamcorder->asm_event_type = ASM_EVENT_MEDIA_MMCAMCORDER;
316                 }
317         } else {
318                 if ((hcamcorder->asm_session_type == MM_SESSION_TYPE_RECORD_AUDIO && info->videodev_type != MM_VIDEO_DEVICE_NONE) ||
319                     (hcamcorder->asm_session_type == MM_SESSION_TYPE_RECORD_VIDEO && info->videodev_type == MM_VIDEO_DEVICE_NONE)) {
320                         ret = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
321                         goto _ERR_DEFAULT_VALUE_INIT;
322                 }
323                 if (hcamcorder->asm_session_type == MM_SESSION_TYPE_RECORD_VIDEO ||
324                     hcamcorder->asm_session_type == MM_SESSION_TYPE_RECORD_AUDIO ||
325                     hcamcorder->asm_session_type == MM_SESSION_TYPE_CALL ||
326                     hcamcorder->asm_session_type == MM_SESSION_TYPE_VIDEOCALL ||
327                     hcamcorder->asm_session_type == MM_SESSION_TYPE_VOIP) {
328                         hcamcorder->asm_register = _MMCamcorder_ASM_NO_NEED_REGISTER;
329                         if (hcamcorder->asm_session_type == MM_SESSION_TYPE_RECORD_AUDIO) {
330                                 hcamcorder->asm_event_type = ASM_EVENT_MMCAMCORDER_AUDIO;
331                         } else {
332                                 hcamcorder->asm_event_type = ASM_EVENT_MMCAMCORDER_VIDEO;
333                         }
334                 } else if (hcamcorder->asm_session_type == MM_SESSION_TYPE_MEDIA || hcamcorder->asm_session_type == MM_SESSION_TYPE_MEDIA_RECORD) {
335                         hcamcorder->asm_register = _MMCamcorder_ASM_SESSION_REGISTERED_BY_OUTSIDE;
336                         hcamcorder->asm_event_type = ASM_EVENT_MEDIA_MMCAMCORDER;
337                 } else {
338                         _mmcam_dbg_err("Not allowed this asm_session_type(%d) for mm-camcorder", hcamcorder->asm_session_type);
339                         ret = MM_ERROR_POLICY_BLOCKED;
340                         goto _ERR_DEFAULT_VALUE_INIT;
341                 }
342         }
343
344         if (hcamcorder->asm_register) {
345                 int pid = -1; /* process id of itself */
346
347                 /* ASM register */
348                 if (!ASM_register_sound(pid, &(hcamcorder->asm_handle), hcamcorder->asm_event_type, ASM_STATE_NONE,
349                                         (ASM_sound_cb_t)_mmcamcorder_asm_callback,
350                                         (void*)hcamcorder, mm_resource, &errorcode)) {
351                         _mmcam_dbg_err("ASM_register_sound() [type %d] failed[%x]", hcamcorder->asm_event_type, errorcode);
352                         ret = MM_ERROR_POLICY_INTERNAL;
353                         goto _ERR_DEFAULT_VALUE_INIT;
354                 }
355                 if (hcamcorder->asm_session_options) {
356                         if(! ASM_set_session_option(hcamcorder->asm_handle, hcamcorder->asm_session_options, &errorcode)) {
357                                 _mmcam_dbg_err("ASM_set_session_options() [options %x] failed[%x]", hcamcorder->asm_session_options, errorcode);
358                                 goto _ERR_AUDIO_BLOCKED;
359                         }
360                 }
361
362                 _mmcam_dbg_log("ASM handle - %d, event type %d, options %x", hcamcorder->asm_handle, hcamcorder->asm_event_type, hcamcorder->asm_session_options);
363         }
364
365         /* Get Camera Configure information from Camcorder INI file */
366         _mmcamcorder_conf_get_info(CONFIGURE_TYPE_MAIN, CONFIGURE_MAIN_FILE, &hcamcorder->conf_main);
367
368         if (!(hcamcorder->conf_main)) {
369                 _mmcam_dbg_err( "Failed to get configure(main) info." );
370
371                 ret = MM_ERROR_CAMCORDER_CREATE_CONFIGURE;
372                 goto _ERR_AUDIO_BLOCKED;
373         }
374
375         hcamcorder->attributes = _mmcamcorder_alloc_attribute((MMHandleType)hcamcorder, info);
376         if (!(hcamcorder->attributes)) {
377                 _mmcam_dbg_err("_mmcamcorder_create::alloc attribute error.");
378
379                 ret = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
380                 goto _ERR_AUDIO_BLOCKED;
381         }
382
383         if (info->videodev_type != MM_VIDEO_DEVICE_NONE) {
384                 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
385                                                 CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
386                                                 "UseConfCtrl", &UseConfCtrl);
387
388                 if (UseConfCtrl) {
389                         int resolution_width = 0;
390                         int resolution_height = 0;
391                         MMCamAttrsInfo fps_info;
392
393                         _mmcam_dbg_log( "Enable Configure Control system." );
394
395                         switch (info->videodev_type) {
396                         case MM_VIDEO_DEVICE_CAMERA0:
397                                 _mmcamcorder_conf_get_value_string(hcamcorder->conf_main,
398                                                                    CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
399                                                                    "ConfCtrlFile0", &ConfCtrlFile);
400                                 break;
401                         case MM_VIDEO_DEVICE_CAMERA1:
402                                 _mmcamcorder_conf_get_value_string(hcamcorder->conf_main,
403                                                                    CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
404                                                                    "ConfCtrlFile1", &ConfCtrlFile);
405                                 break;
406                         default:
407                                 _mmcam_dbg_err( "Not supported camera type." );
408                                 ret = MM_ERROR_CAMCORDER_NOT_SUPPORTED;
409                                 goto _ERR_ALLOC_ATTRIBUTE;
410                         }
411
412                         _mmcam_dbg_log("videodev_type : [%d], ConfCtrlPath : [%s]", info->videodev_type, ConfCtrlFile);
413
414                         _mmcamcorder_conf_get_info(CONFIGURE_TYPE_CTRL, ConfCtrlFile, &hcamcorder->conf_ctrl);
415 /*
416                         _mmcamcorder_conf_print_info(&hcamcorder->conf_main);
417                         _mmcamcorder_conf_print_info(&hcamcorder->conf_ctrl);
418 */
419                         if (!(hcamcorder->conf_ctrl)) {
420                                 _mmcam_dbg_err( "Failed to get configure(control) info." );
421                                 ret = MM_ERROR_CAMCORDER_NOT_SUPPORTED;
422                                 goto _ERR_ALLOC_ATTRIBUTE;
423                         }
424
425                         ret = _mmcamcorder_init_convert_table((MMHandleType)hcamcorder);
426                         if (ret != MM_ERROR_NONE) {
427                                 _mmcam_dbg_warn("converting table initialize error!!");
428                                 ret = MM_ERROR_CAMCORDER_INTERNAL;
429                                 goto _ERR_ALLOC_ATTRIBUTE;
430                         }
431
432                         ret = _mmcamcorder_init_attr_from_configure((MMHandleType)hcamcorder, info->videodev_type);
433                         if (ret != MM_ERROR_NONE) {
434                                 _mmcam_dbg_warn("converting table initialize error!!");
435                                 ret = MM_ERROR_CAMCORDER_INTERNAL;
436                                 goto _ERR_ALLOC_ATTRIBUTE;
437                         }
438
439                         /* Get device info, recommend preview fmt and display rotation from INI */
440                         _mmcamcorder_conf_get_value_int(hcamcorder->conf_ctrl,
441                                                         CONFIGURE_CATEGORY_CTRL_CAMERA,
442                                                         "RecommendPreviewFormatCapture",
443                                                         &rcmd_fmt_capture);
444
445                         _mmcamcorder_conf_get_value_int(hcamcorder->conf_ctrl,
446                                                         CONFIGURE_CATEGORY_CTRL_CAMERA,
447                                                         "RecommendPreviewFormatRecord",
448                                                         &rcmd_fmt_recording);
449
450                         _mmcamcorder_conf_get_value_int(hcamcorder->conf_ctrl,
451                                                         CONFIGURE_CATEGORY_CTRL_CAMERA,
452                                                         "RecommendDisplayRotation",
453                                                         &rcmd_dpy_rotation);
454
455                         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
456                                                         CONFIGURE_CATEGORY_MAIN_CAPTURE,
457                                                         "PlayCaptureSound",
458                                                         &play_capture_sound);
459
460                         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
461                                                         CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
462                                                         "DeviceCount",
463                                                         &camera_device_count);
464
465                         _mmcamcorder_conf_get_value_int(hcamcorder->conf_ctrl,
466                                                         CONFIGURE_CATEGORY_CTRL_CAMERA,
467                                                         "FacingDirection",
468                                                         &camera_facing_direction);
469
470                         _mmcamcorder_conf_get_value_int(hcamcorder->conf_ctrl,
471                                                         CONFIGURE_CATEGORY_CTRL_EFFECT,
472                                                         "BrightnessStepDenominator",
473                                                         &hcamcorder->brightness_step_denominator);
474
475                         _mmcamcorder_conf_get_value_int(hcamcorder->conf_ctrl,
476                                                         CONFIGURE_CATEGORY_CTRL_CAPTURE,
477                                                         "SupportZSL",
478                                                         &hcamcorder->support_zsl_capture);
479
480                         _mmcam_dbg_log("Recommend fmt[cap:%d,rec:%d], dpy rot %d, cap snd %d, dev cnt %d, cam facing dir %d, step denom %d, support zsl %d",
481                                        rcmd_fmt_capture, rcmd_fmt_recording, rcmd_dpy_rotation,
482                                        play_capture_sound, camera_device_count, camera_facing_direction,
483                                        hcamcorder->brightness_step_denominator, hcamcorder->support_zsl_capture);
484
485                         /* Get UseZeroCopyFormat value from INI */
486                         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
487                                                         CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
488                                                         "UseZeroCopyFormat",
489                                                         &(hcamcorder->use_zero_copy_format));
490
491                         /* Get SupportMediaPacketPreviewCb value from INI */
492                         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
493                                                         CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
494                                                         "SupportMediaPacketPreviewCb",
495                                                         &(hcamcorder->support_media_packet_preview_cb));
496
497                         ret = mm_camcorder_get_attributes((MMHandleType)hcamcorder, NULL,
498                                                     MMCAM_CAMERA_WIDTH, &resolution_width,
499                                                     MMCAM_CAMERA_HEIGHT, &resolution_height,
500                                                     NULL);
501
502                         mm_camcorder_get_fps_list_by_resolution((MMHandleType)hcamcorder, resolution_width, resolution_height, &fps_info);
503
504                         _mmcam_dbg_log("UseZeroCopyFormat : %d", hcamcorder->use_zero_copy_format);
505                         _mmcam_dbg_log("SupportMediaPacketPreviewCb : %d", hcamcorder->support_media_packet_preview_cb);
506                         _mmcam_dbg_log("res : %d X %d, Default FPS by resolution  : %d", resolution_width, resolution_height, fps_info.int_array.def);
507
508                         if (camera_facing_direction == 1) {
509                                 if (rcmd_dpy_rotation == MM_DISPLAY_ROTATION_270 || rcmd_dpy_rotation == MM_DISPLAY_ROTATION_90) {
510                                         camera_default_flip = MM_FLIP_VERTICAL;
511                                 } else {
512                                         camera_default_flip = MM_FLIP_HORIZONTAL;
513                                 }
514                                 _mmcam_dbg_log("camera_default_flip : [%d]",camera_default_flip);
515                         }
516
517                         mm_camcorder_set_attributes((MMHandleType)hcamcorder, &err_attr_name,
518                                                     MMCAM_CAMERA_DEVICE_COUNT, camera_device_count,
519                                                     MMCAM_CAMERA_FACING_DIRECTION, camera_facing_direction,
520                                                     MMCAM_RECOMMEND_PREVIEW_FORMAT_FOR_CAPTURE, rcmd_fmt_capture,
521                                                     MMCAM_RECOMMEND_PREVIEW_FORMAT_FOR_RECORDING, rcmd_fmt_recording,
522                                                     MMCAM_RECOMMEND_DISPLAY_ROTATION, rcmd_dpy_rotation,
523                                                     MMCAM_SUPPORT_ZSL_CAPTURE, hcamcorder->support_zsl_capture,
524                                                     MMCAM_SUPPORT_ZERO_COPY_FORMAT, hcamcorder->use_zero_copy_format,
525                                                     MMCAM_SUPPORT_MEDIA_PACKET_PREVIEW_CB, hcamcorder->support_media_packet_preview_cb,
526                                                     MMCAM_CAMERA_FPS, fps_info.int_array.def,
527                                                     MMCAM_DISPLAY_FLIP, camera_default_flip,
528                                                     "capture-sound-enable", play_capture_sound,
529                                                     NULL);
530                         if (err_attr_name) {
531                                 _mmcam_dbg_err("Set %s FAILED.", err_attr_name);
532                                 free(err_attr_name);
533                                 err_attr_name = NULL;
534                                 ret = MM_ERROR_CAMCORDER_INTERNAL;
535                                 goto _ERR_ALLOC_ATTRIBUTE;
536                         }
537
538                         /* Get default value of brightness */
539                         mm_camcorder_get_attributes((MMHandleType)hcamcorder, &err_attr_name,
540                                                     MMCAM_FILTER_BRIGHTNESS, &hcamcorder->brightness_default,
541                                                     NULL);
542                         if (err_attr_name) {
543                                 _mmcam_dbg_err("Get brightness FAILED.");
544                                 free(err_attr_name);
545                                 err_attr_name = NULL;
546                                 ret = MM_ERROR_CAMCORDER_INTERNAL;
547                                 goto _ERR_ALLOC_ATTRIBUTE;
548                         }
549                         _mmcam_dbg_log("Default brightness : %d", hcamcorder->brightness_default);
550                 } else {
551                         _mmcam_dbg_log( "Disable Configure Control system." );
552                         hcamcorder->conf_ctrl = NULL;
553                 }
554         } else {
555                 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
556                                                     CONFIGURE_CATEGORY_MAIN_VIDEO_INPUT,
557                                                     "DeviceCount",
558                                                     &camera_device_count);
559                 mm_camcorder_set_attributes((MMHandleType)hcamcorder, &err_attr_name,
560                                                     MMCAM_CAMERA_DEVICE_COUNT, camera_device_count,
561                                                     NULL);
562                 if (err_attr_name) {
563                         _mmcam_dbg_err("Set %s FAILED.", err_attr_name);
564                         free(err_attr_name);
565                         err_attr_name = NULL;
566                         ret = MM_ERROR_CAMCORDER_INTERNAL;
567                         goto _ERR_ALLOC_ATTRIBUTE;
568                 }
569
570                 ret = _mmcamcorder_init_attr_from_configure((MMHandleType)hcamcorder, info->videodev_type);
571                 if (ret != MM_ERROR_NONE) {
572                         _mmcam_dbg_warn("converting table initialize error!!");
573                         ret = MM_ERROR_CAMCORDER_INTERNAL;
574                         goto _ERR_ALLOC_ATTRIBUTE;
575                 }
576         }
577         traceBegin(TTRACE_TAG_CAMERA, "MMCAMCORDER:CREATE:INIT_GSTREAMER");
578
579         ret = __mmcamcorder_gstreamer_init(hcamcorder->conf_main);
580
581         traceEnd(TTRACE_TAG_CAMERA);
582
583         if (!ret) {
584                 _mmcam_dbg_err( "Failed to initialize gstreamer!!" );
585                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
586                 goto _ERR_ALLOC_ATTRIBUTE;
587         }
588
589         /* Make some attributes as read-only type */
590         _mmcamcorder_lock_readonly_attributes((MMHandleType)hcamcorder);
591
592         /* Disable attributes in each model */
593         _mmcamcorder_set_disabled_attributes((MMHandleType)hcamcorder);
594
595         /* Get videosink name for evas surface */
596         _mmcamcorder_conf_get_element(hcamcorder->conf_main,
597                                       CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
598                                       "VideosinkElementEvas",
599                                       &EvasSurfaceElement);
600         if (EvasSurfaceElement) {
601                 int attr_index = 0;
602                 const char *evassink_name = NULL;
603                 mmf_attribute_t *item_evassink_name = NULL;
604                 mmf_attrs_t *attrs = (mmf_attrs_t *)MMF_CAMCORDER_ATTRS(hcamcorder);
605
606                 _mmcamcorder_conf_get_value_element_name(EvasSurfaceElement, &evassink_name);
607                 mm_attrs_get_index((MMHandleType)attrs, MMCAM_DISPLAY_EVAS_SURFACE_SINK, &attr_index);
608                 item_evassink_name = &attrs->items[attr_index];
609                 mmf_attribute_set_string(item_evassink_name, evassink_name, strlen(evassink_name));
610                 mmf_attribute_commit(item_evassink_name);
611
612                 _mmcam_dbg_log("Evassink name : %s", evassink_name);
613         }
614
615         /* get shutter sound policy */
616         vconf_get_int(VCONFKEY_CAMERA_SHUTTER_SOUND_POLICY, &hcamcorder->shutter_sound_policy);
617         _mmcam_dbg_log("current shutter sound policy : %d", hcamcorder->shutter_sound_policy);
618
619         /* get model name */
620         system_info_get_platform_string("http://tizen.org/system/model_name", &hcamcorder->model_name);
621
622         /* get software version */
623         system_info_get_platform_string("http://tizen.org/system/build.string", &hcamcorder->software_version);
624
625         /* Set initial state */
626         _mmcamcorder_set_state((MMHandleType)hcamcorder, MM_CAMCORDER_STATE_NULL);
627
628         _mmcam_dbg_log("created handle %p", hcamcorder);
629
630         /* set device type */
631         g_mm_camcorder_type = info->videodev_type;
632
633         *handle = (MMHandleType)hcamcorder;
634
635         return MM_ERROR_NONE;
636
637 _ERR_ALLOC_ATTRIBUTE:
638 _ERR_AUDIO_BLOCKED:
639         /* unregister audio session manager */
640         if(hcamcorder->asm_register) {
641                 int res = MM_ERROR_NONE;
642                 /* unregister ASM */
643                 if (!ASM_unregister_sound(hcamcorder->asm_handle, hcamcorder->asm_event_type, &errorcode)) {
644                         _mmcam_dbg_err("ASM_unregister_sound() MMCAMCORDER_AUDIO failed(hdl:%p, stype:%d, err:%x)",
645                                        (void*)hcamcorder->asm_handle, hcamcorder->asm_session_type, errorcode);
646                 }
647                 /* Update session information */
648                 if (hcamcorder->asm_register == _MMCamcorder_ASM_SESSION_REGISTERED_INTERNALLY) {
649                         /* Remove session information */
650                         res = _mm_session_util_delete_information(-1);
651                         if (res) {
652                                 _mmcam_dbg_err("_mm_session_util_delete_information() failed[%x]", res);
653                         }
654                 }
655         }
656
657 _ERR_DEFAULT_VALUE_INIT:
658         /* Release lock, cond */
659         pthread_mutex_destroy(&((hcamcorder->mtsafe).lock));
660         pthread_cond_destroy(&((hcamcorder->mtsafe).cond));
661         pthread_mutex_destroy(&((hcamcorder->mtsafe).cmd_lock));
662         pthread_cond_destroy(&((hcamcorder->mtsafe).cmd_cond));
663         pthread_mutex_destroy(&((hcamcorder->mtsafe).asm_lock));
664         pthread_mutex_destroy(&((hcamcorder->mtsafe).state_lock));
665         pthread_mutex_destroy(&((hcamcorder->mtsafe).gst_state_lock));
666         pthread_mutex_destroy(&((hcamcorder->mtsafe).gst_encode_state_lock));
667         pthread_mutex_destroy(&((hcamcorder->mtsafe).message_cb_lock));
668         pthread_mutex_destroy(&((hcamcorder->mtsafe).vcapture_cb_lock));
669         pthread_mutex_destroy(&((hcamcorder->mtsafe).vstream_cb_lock));
670         pthread_mutex_destroy(&((hcamcorder->mtsafe).astream_cb_lock));
671
672         pthread_mutex_destroy(&(hcamcorder->sound_lock));
673         pthread_cond_destroy(&(hcamcorder->sound_cond));
674         pthread_mutex_destroy(&(hcamcorder->snd_info.open_mutex));
675         pthread_cond_destroy(&(hcamcorder->snd_info.open_cond));
676         pthread_mutex_destroy(&(hcamcorder->restart_preview_lock));
677
678         if (hcamcorder->conf_ctrl) {
679                 _mmcamcorder_conf_release_info( &hcamcorder->conf_ctrl );
680         }
681
682         if (hcamcorder->conf_main) {
683                 _mmcamcorder_conf_release_info( &hcamcorder->conf_main );
684         }
685
686         if (hcamcorder->model_name) {
687                 free(hcamcorder->model_name);
688                 hcamcorder->model_name = NULL;
689         }
690
691         if (hcamcorder->software_version) {
692                 free(hcamcorder->software_version);
693                 hcamcorder->software_version = NULL;
694         }
695
696         if (hcamcorder->task_thread) {
697                 pthread_mutex_lock(&(hcamcorder->task_thread_lock));
698                 _mmcam_dbg_log("send signal for task thread exit");
699                 hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_EXIT;
700                 pthread_cond_signal(&(hcamcorder->task_thread_cond));
701                 pthread_mutex_unlock(&(hcamcorder->task_thread_lock));
702                 pthread_join(hcamcorder->task_thread, NULL);
703         }
704         pthread_mutex_destroy(&(hcamcorder->task_thread_lock));
705         pthread_cond_destroy(&(hcamcorder->task_thread_cond));
706
707         /* Release handle */
708         memset(hcamcorder, 0x00, sizeof(mmf_camcorder_t));
709         free(hcamcorder);
710
711         return ret;
712 }
713
714
715 int _mmcamcorder_destroy(MMHandleType handle)
716 {
717         int ret = MM_ERROR_NONE;
718         int state = MM_CAMCORDER_STATE_NONE;
719         int state_FROM = MM_CAMCORDER_STATE_NULL;
720         int errorcode = MM_ERROR_NONE;
721
722         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
723
724         _mmcam_dbg_log("");
725
726         if (!hcamcorder) {
727                 _mmcam_dbg_err("Not initialized");
728                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
729                 goto _ERR_CAMCORDER_CMD_PRECON;
730         }
731
732         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
733                 _mmcam_dbg_err("Another command is running.");
734                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
735                 goto _ERR_CAMCORDER_CMD_PRECON;
736         }
737
738         state = _mmcamcorder_get_state(handle);
739         if (state != state_FROM) {
740                 _mmcam_dbg_err("Wrong state(%d)", state);
741                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
742                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
743         }
744
745         /* set exit state for sound thread */
746         pthread_mutex_lock(&(hcamcorder->task_thread_lock));
747         _mmcam_dbg_log("send signal for task thread exit");
748         hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_EXIT;
749         pthread_cond_signal(&(hcamcorder->task_thread_cond));
750         pthread_mutex_unlock(&(hcamcorder->task_thread_lock));
751
752         pthread_mutex_lock(&(hcamcorder->sound_lock));
753         while (hcamcorder->capture_sound_count > 0) {
754                 struct timespec timeout;
755                 struct timeval tv;
756
757                 gettimeofday(&tv, NULL);
758                 timeout.tv_sec = tv.tv_sec + __MMCAMCORDER_SOUND_WAIT_TIMEOUT;
759                 timeout.tv_nsec = tv.tv_usec * 1000;
760
761                 _mmcam_dbg_warn("capture_sound_count[%d] is not zero. wait signal...",
762                                 hcamcorder->capture_sound_count);
763
764                 if (!pthread_cond_timedwait(&(hcamcorder->sound_cond), &(hcamcorder->sound_lock), &timeout)) {
765                         _mmcam_dbg_warn("signal received. check again...");
766                 } else {
767                         hcamcorder->capture_sound_count = 0;
768                         _mmcam_dbg_err("capture sound completion wait time out");
769                         break;
770                 }
771         }
772         pthread_mutex_unlock(&(hcamcorder->sound_lock));
773
774         /* Release SubContext and pipeline */
775         if (hcamcorder->sub_context) {
776                 if (hcamcorder->sub_context->element) {
777                         _mmcamcorder_destroy_pipeline(handle, hcamcorder->type);
778                 }
779
780                 _mmcamcorder_dealloc_subcontext(hcamcorder->sub_context);
781                 hcamcorder->sub_context = NULL;
782         }
783
784         /* Remove idle function which is not called yet */
785         if (hcamcorder->setting_event_id) {
786                 _mmcam_dbg_log("Remove remaining idle function");
787                 g_source_remove(hcamcorder->setting_event_id);
788                 hcamcorder->setting_event_id = 0;
789         }
790
791         /* check current strobe mode */
792         if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
793                 pid_t my_pid = getpid();
794                 int camera_pid = -1;
795                 vconf_get_int(VCONFKEY_CAMERA_PID, &camera_pid);
796
797                 if (camera_pid > -1 && my_pid == camera_pid) {
798                         int strobe_mode = MM_CAMCORDER_STROBE_MODE_OFF;
799
800                         vconf_set_int(VCONFKEY_CAMERA_PID, -1);
801                         _mmcam_dbg_log("reset camera pid");
802
803                         mm_camcorder_get_attributes(handle, NULL,
804                                                     MMCAM_STROBE_MODE, &strobe_mode,
805                                                     NULL);
806                         if (strobe_mode != MM_CAMCORDER_STROBE_MODE_OFF) {
807                                 /* set OFF state of vconf key */
808                                 vconf_set_int(VCONFKEY_CAMERA_FLASH_STATE, VCONFKEY_CAMERA_FLASH_STATE_OFF);
809                                 _mmcam_dbg_log("reset flash state");
810                         }
811                 }
812         }
813
814         /* Remove attributes */
815         if (hcamcorder->attributes) {
816                 _mmcamcorder_dealloc_attribute(hcamcorder->attributes);
817                 hcamcorder->attributes = 0;
818         }
819
820         /* Remove exif info */
821         if (hcamcorder->exif_info) {
822                 mm_exif_destory_exif_info(hcamcorder->exif_info);
823                 hcamcorder->exif_info=NULL;
824
825         }
826
827         /* Release configure info */
828         if (hcamcorder->conf_ctrl) {
829                 _mmcamcorder_conf_release_info( &hcamcorder->conf_ctrl );
830         }
831         if (hcamcorder->conf_main) {
832                 _mmcamcorder_conf_release_info( &hcamcorder->conf_main );
833         }
834
835         /* Remove messages which are not called yet */
836         _mmcamcorder_remove_message_all(handle);
837
838         if (hcamcorder->asm_register) {
839                 /* Unregister ASM */
840                 if (!ASM_unregister_sound(hcamcorder->asm_handle, hcamcorder->asm_event_type, &errorcode)) {
841                         _mmcam_dbg_err("ASM_unregister_sound() failed(hdl:%p, err:%x)",
842                                        (void*)hcamcorder->asm_handle, errorcode);
843                 }
844                 /* Update session information */
845                 if (hcamcorder->asm_register == _MMCamcorder_ASM_SESSION_REGISTERED_INTERNALLY) {
846                         int res = MM_ERROR_NONE;
847                         /* Remove session information */
848                         res = _mm_session_util_delete_information(-1);
849                         if (res) {
850                                 _mmcam_dbg_err("_mm_session_util_delete_information() failed[%x]", res);
851                         }
852                 }
853         }
854
855         /* release model_name */
856         if (hcamcorder->model_name) {
857                 free(hcamcorder->model_name);
858                 hcamcorder->model_name = NULL;
859         }
860
861         if (hcamcorder->software_version) {
862                 free(hcamcorder->software_version);
863                 hcamcorder->software_version = NULL;
864         }
865
866         /* join task thread */
867         _mmcam_dbg_log("task thread join");
868         pthread_join(hcamcorder->task_thread, NULL);
869
870         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
871
872         /* Release lock, cond */
873         pthread_mutex_destroy(&((hcamcorder->mtsafe).lock));
874         pthread_cond_destroy(&((hcamcorder->mtsafe).cond));
875         pthread_mutex_destroy(&((hcamcorder->mtsafe).cmd_lock));
876         pthread_cond_destroy(&((hcamcorder->mtsafe).cmd_cond));
877         pthread_mutex_destroy(&((hcamcorder->mtsafe).asm_lock));
878         pthread_mutex_destroy(&((hcamcorder->mtsafe).state_lock));
879         pthread_mutex_destroy(&((hcamcorder->mtsafe).gst_state_lock));
880         pthread_mutex_destroy(&((hcamcorder->mtsafe).gst_encode_state_lock));
881         pthread_mutex_destroy(&((hcamcorder->mtsafe).message_cb_lock));
882         pthread_mutex_destroy(&((hcamcorder->mtsafe).vcapture_cb_lock));
883         pthread_mutex_destroy(&((hcamcorder->mtsafe).vstream_cb_lock));
884         pthread_mutex_destroy(&((hcamcorder->mtsafe).astream_cb_lock));
885
886         pthread_mutex_destroy(&(hcamcorder->sound_lock));
887         pthread_cond_destroy(&(hcamcorder->sound_cond));
888         pthread_mutex_destroy(&(hcamcorder->snd_info.open_mutex));
889         pthread_cond_destroy(&(hcamcorder->snd_info.open_cond));
890         pthread_mutex_destroy(&(hcamcorder->restart_preview_lock));
891         pthread_mutex_destroy(&(hcamcorder->task_thread_lock));
892         pthread_cond_destroy(&(hcamcorder->task_thread_cond));
893
894         /* Release external root directory string */
895         if (hcamcorder->root_directory) {
896                 free(hcamcorder->root_directory);
897                 hcamcorder->root_directory = NULL;
898         }
899
900         /* Release handle */
901         memset(hcamcorder, 0x00, sizeof(mmf_camcorder_t));
902         free(hcamcorder);
903
904         return MM_ERROR_NONE;
905
906 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
907         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
908
909 _ERR_CAMCORDER_CMD_PRECON:
910         if (hcamcorder) {
911                 _mmcam_dbg_err("Destroy fail (type %d, state %d)", hcamcorder->type, state);
912         }
913
914         _mmcam_dbg_err("Destroy fail (ret %x)", ret);
915
916         return ret;
917 }
918
919
920 int _mmcamcorder_realize(MMHandleType handle)
921 {
922         int ret = MM_ERROR_NONE;
923         int state = MM_CAMCORDER_STATE_NONE;
924         int state_FROM = MM_CAMCORDER_STATE_NULL;
925         int state_TO = MM_CAMCORDER_STATE_READY;
926         int errorcode = MM_ERROR_NONE;
927         ASM_resource_t mm_resource = ASM_RESOURCE_NONE;
928         int display_surface_type = MM_DISPLAY_SURFACE_X;
929         double motion_rate = _MMCAMCORDER_DEFAULT_RECORDING_MOTION_RATE;
930         char *videosink_element_type = NULL;
931         const char *videosink_name = NULL;
932         char err_msg[MAX_ERROR_MESSAGE_LEN] = {'\0',};
933
934         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
935
936         /*_mmcam_dbg_log("");*/
937
938         if (!hcamcorder) {
939                 _mmcam_dbg_err("Not initialized");
940                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
941                 return ret;
942         }
943
944         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
945                 _mmcam_dbg_err("Another command is running.");
946                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
947                 goto _ERR_CAMCORDER_CMD_PRECON;
948         }
949
950         state = _mmcamcorder_get_state(handle);
951         if (state != state_FROM) {
952                 _mmcam_dbg_err("Wrong state(%d)", state);
953                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
954                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
955         }
956
957         mm_camcorder_get_attributes(handle, NULL,
958                                     MMCAM_MODE, &hcamcorder->type,
959                                     NULL);
960
961         /* Get profile mode */
962         _mmcam_dbg_log("Profile mode [%d]", hcamcorder->type);
963
964         mm_camcorder_get_attributes(handle, NULL,
965                                     MMCAM_DISPLAY_SURFACE, &display_surface_type,
966                                     MMCAM_CAMERA_RECORDING_MOTION_RATE, &motion_rate,
967                                     NULL);
968
969         /* Check and make SHARE session as PLAYING */
970         if (hcamcorder->asm_register) {
971                 switch (hcamcorder->type) {
972                 case MM_CAMCORDER_MODE_AUDIO:
973                         mm_resource = ASM_RESOURCE_NONE;
974                         break;
975                 case MM_CAMCORDER_MODE_VIDEO_CAPTURE:
976                 default:
977                         mm_resource = ASM_RESOURCE_CAMERA | ASM_RESOURCE_HW_ENCODER;
978
979                         if (display_surface_type == MM_DISPLAY_SURFACE_X ||
980                         display_surface_type == MM_DISPLAY_SURFACE_X_EXT) {
981                                 mm_resource |= ASM_RESOURCE_VIDEO_OVERLAY;
982                                 _mmcam_dbg_warn("VIDEO_OVERLAY resource INCLUDED");
983                         } else {
984                                 _mmcam_dbg_warn("VIDEO_OVERLAY resource EXCLUDED");
985                         }
986                         break;
987                 }
988
989                 if (!ASM_set_sound_state(hcamcorder->asm_handle, hcamcorder->asm_event_type,
990                                          ASM_STATE_PLAYING, mm_resource, &errorcode)) {
991                         switch (errorcode) {
992                         case ERR_ASM_POLICY_CANNOT_PLAY_BY_CALL:
993                                 ret = MM_ERROR_POLICY_BLOCKED_BY_CALL;
994                                 break;
995                         case ERR_ASM_POLICY_CANNOT_PLAY_BY_ALARM:
996                                 ret = MM_ERROR_POLICY_BLOCKED_BY_ALARM;
997                                 break;
998                         default:
999                                 ret = MM_ERROR_POLICY_BLOCKED;
1000                                 break;
1001                         }
1002
1003                         _mmcam_dbg_err("Set ASM state to playing failed errorcode: 0x%x, ret: 0x%x", errorcode, ret);
1004
1005                         goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1006                 }
1007         } else if (hcamcorder->asm_session_type == MM_SESSION_TYPE_RECORD_VIDEO ||
1008                    hcamcorder->asm_session_type == MM_SESSION_TYPE_RECORD_AUDIO) {
1009                 /* ASM attach callback - application can remove ASM callback by destroy session */
1010                 if (!ASM_attach_callback(hcamcorder->asm_event_type, _mmcamcorder_asm_callback,
1011                                          (void*)hcamcorder, &errorcode)) {
1012                         if (errorcode == ERR_ASM_ALREADY_REGISTERED) {
1013                                 _mmcam_dbg_warn("ASM callback is already registered");
1014                         } else {
1015                                 _mmcam_dbg_err("ASM_attach_callback() [type %d] failed[%x]", hcamcorder->asm_event_type, errorcode);
1016                                 ret = MM_ERROR_POLICY_INTERNAL;
1017                                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1018                         }
1019                 }
1020
1021                 _mmcam_dbg_log("attached ASM callback - evnet type %d", hcamcorder->asm_event_type);
1022         } else {
1023                 _mmcam_dbg_log("do nothing for ASM");
1024         }
1025
1026         /* set camera/recorder state to vconf key */
1027         if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
1028                 int vconf_camera_state = 0;
1029
1030                 /* get current camera state of vconf key */
1031                 vconf_get_int(VCONFKEY_CAMERA_STATE, &vconf_camera_state);
1032                 if (vconf_set_int(VCONFKEY_CAMERA_STATE, VCONFKEY_CAMERA_STATE_OPEN)) {
1033                         strerror_r(errno, err_msg, MAX_ERROR_MESSAGE_LEN);
1034                         _mmcam_dbg_log("VCONF ERROR %s : cur %d",err_msg,errno);
1035                         if(errno == EPERM || errno == EACCES) {
1036                                 ret = MM_ERROR_COMMON_INVALID_PERMISSION;
1037                                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_SESSION;
1038                         }
1039                 }
1040                 _mmcam_dbg_log("VCONFKEY_CAMERA_STATE prev %d -> cur %d",
1041                                vconf_camera_state, VCONFKEY_CAMERA_STATE_OPEN);
1042         } else {
1043                 int vconf_recorder_state = 0;
1044
1045                 /* get current recorder state of vconf key */
1046                 vconf_get_int(VCONFKEY_RECORDER_STATE, &vconf_recorder_state);
1047                 if (vconf_set_int(VCONFKEY_RECORDER_STATE, VCONFKEY_RECORDER_STATE_CREATED)) {
1048                         strerror_r(errno, err_msg, MAX_ERROR_MESSAGE_LEN);
1049                         _mmcam_dbg_log("VCONF ERROR %s : cur %d",err_msg,errno);
1050                         if (errno == EPERM || errno == EACCES) {
1051                                 ret = MM_ERROR_COMMON_INVALID_PERMISSION;
1052                                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_SESSION;
1053                         }
1054                 }
1055
1056                 _mmcam_dbg_log("VCONFKEY_RECORDER_STATE prev %d -> cur %d",
1057                                vconf_recorder_state, VCONFKEY_RECORDER_STATE_CREATED);
1058         }
1059
1060         /* alloc sub context */
1061         hcamcorder->sub_context = _mmcamcorder_alloc_subcontext(hcamcorder->type);
1062         if(!hcamcorder->sub_context) {
1063                 ret = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1064                 goto _ERR_CAMCORDER_CMD;
1065         }
1066
1067         /* Set basic configure information */
1068         if (motion_rate != _MMCAMCORDER_DEFAULT_RECORDING_MOTION_RATE) {
1069                 hcamcorder->sub_context->is_modified_rate = TRUE;
1070         }
1071
1072         _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
1073                                         CONFIGURE_CATEGORY_MAIN_CAPTURE,
1074                                         "UseEncodebin",
1075                                         &(hcamcorder->sub_context->bencbin_capture));
1076         _mmcam_dbg_warn("UseEncodebin [%d]", hcamcorder->sub_context->bencbin_capture);
1077
1078         if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
1079                 /* get dual stream support info */
1080                 _mmcamcorder_conf_get_value_int(hcamcorder->conf_main,
1081                                                 CONFIGURE_CATEGORY_MAIN_RECORD,
1082                                                 "SupportDualStream",
1083                                                 &(hcamcorder->sub_context->info_video->support_dual_stream));
1084                 _mmcam_dbg_warn("SupportDualStream [%d]", hcamcorder->sub_context->info_video->support_dual_stream);
1085         }
1086
1087         switch (display_surface_type) {
1088         case MM_DISPLAY_SURFACE_X:
1089         case MM_DISPLAY_SURFACE_X_EXT:
1090                 videosink_element_type = strdup("VideosinkElementX");
1091                 break;
1092         case MM_DISPLAY_SURFACE_EVAS:
1093                 videosink_element_type = strdup("VideosinkElementEvas");
1094                 break;
1095         case MM_DISPLAY_SURFACE_GL:
1096                 videosink_element_type = strdup("VideosinkElementGL");
1097                 break;
1098         case MM_DISPLAY_SURFACE_NULL:
1099                 videosink_element_type = strdup("VideosinkElementNull");
1100                 break;
1101         default:
1102                 videosink_element_type = strdup("VideosinkElementX");
1103                 break;
1104         }
1105
1106         /* check string of videosink element */
1107         if (videosink_element_type) {
1108                 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
1109                                               CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
1110                                               videosink_element_type,
1111                                               &hcamcorder->sub_context->VideosinkElement);
1112                 free(videosink_element_type);
1113                 videosink_element_type = NULL;
1114         } else {
1115                 _mmcam_dbg_warn("strdup failed(display_surface_type %d). Use default X type",
1116                                 display_surface_type);
1117
1118                 _mmcamcorder_conf_get_element(hcamcorder->conf_main,
1119                                               CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
1120                                               _MMCAMCORDER_DEFAULT_VIDEOSINK_TYPE,
1121                                               &hcamcorder->sub_context->VideosinkElement);
1122         }
1123
1124         _mmcamcorder_conf_get_value_element_name(hcamcorder->sub_context->VideosinkElement, &videosink_name);
1125         _mmcam_dbg_log("Videosink name : %s", videosink_name);
1126
1127         /* get videoconvert element */
1128         _mmcamcorder_conf_get_element(hcamcorder->conf_main,
1129                                       CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
1130                                       "VideoconvertElement",
1131                                       &hcamcorder->sub_context->VideoconvertElement);
1132
1133         _mmcamcorder_conf_get_value_int(hcamcorder->conf_ctrl,
1134                                         CONFIGURE_CATEGORY_CTRL_CAPTURE,
1135                                         "SensorEncodedCapture",
1136                                         &(hcamcorder->sub_context->SensorEncodedCapture));
1137         _mmcam_dbg_log("Support sensor encoded capture : %d", hcamcorder->sub_context->SensorEncodedCapture);
1138
1139         /* create pipeline */
1140         traceBegin(TTRACE_TAG_CAMERA, "MMCAMCORDER:REALIZE:CREATE_PIPELINE");
1141         ret = _mmcamcorder_create_pipeline(handle, hcamcorder->type);
1142         traceEnd(TTRACE_TAG_CAMERA);
1143         if (ret != MM_ERROR_NONE) {
1144                 /* check internal error of gstreamer */
1145                 if (hcamcorder->error_code != MM_ERROR_NONE) {
1146                         ret = hcamcorder->error_code;
1147                         _mmcam_dbg_log("gstreamer error is occurred. return it %x", ret);
1148                 }
1149
1150                 /* release sub context */
1151                 _mmcamcorder_dealloc_subcontext(hcamcorder->sub_context);
1152                 hcamcorder->sub_context = NULL;
1153                 goto _ERR_CAMCORDER_CMD;
1154         }
1155
1156         /* set command function */
1157         ret = _mmcamcorder_set_functions(handle, hcamcorder->type);
1158         if (ret != MM_ERROR_NONE) {
1159                 _mmcamcorder_destroy_pipeline(handle, hcamcorder->type);
1160                 _mmcamcorder_dealloc_subcontext(hcamcorder->sub_context);
1161                 hcamcorder->sub_context = NULL;
1162                 goto _ERR_CAMCORDER_CMD;
1163         }
1164
1165         _mmcamcorder_set_state(handle, state_TO);
1166
1167         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1168
1169         return MM_ERROR_NONE;
1170
1171 _ERR_CAMCORDER_CMD:
1172         /* rollback camera state to vconf key */
1173         if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
1174                 int vconf_camera_state = 0;
1175
1176                 /* get current camera state of vconf key */
1177                 vconf_get_int(VCONFKEY_CAMERA_STATE, &vconf_camera_state);
1178                 vconf_set_int(VCONFKEY_CAMERA_STATE, VCONFKEY_CAMERA_STATE_NULL);
1179
1180                 _mmcam_dbg_log("VCONFKEY_CAMERA_STATE prev %d -> cur %d",
1181                                vconf_camera_state, VCONFKEY_CAMERA_STATE_NULL);
1182         } else {
1183                 int vconf_recorder_state = 0;
1184
1185                 /* get current recorder state of vconf key */
1186                 vconf_get_int(VCONFKEY_RECORDER_STATE, &vconf_recorder_state);
1187                 vconf_set_int(VCONFKEY_RECORDER_STATE, VCONFKEY_RECORDER_STATE_NULL);
1188
1189                 _mmcam_dbg_log("VCONFKEY_RECORDER_STATE prev %d -> cur %d",
1190                                vconf_recorder_state, VCONFKEY_RECORDER_STATE_NULL);
1191         }
1192
1193 _ERR_CAMCORDER_CMD_PRECON_AFTER_SESSION:
1194         if (hcamcorder->asm_register) {
1195                 /* STOP session */
1196                 if (!ASM_set_sound_state(hcamcorder->asm_handle, hcamcorder->asm_event_type,
1197                                          ASM_STATE_STOP, mm_resource, &errorcode)) {
1198                         _mmcam_dbg_err("Set ASM state to STOP failed 0x%x", errorcode);
1199                 }
1200         }
1201
1202 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
1203         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1204
1205 _ERR_CAMCORDER_CMD_PRECON:
1206         _mmcam_dbg_err("Realize fail (type %d, state %d, ret %x)",
1207                        hcamcorder->type, state, ret);
1208
1209         return ret;
1210 }
1211
1212
1213 int _mmcamcorder_unrealize(MMHandleType handle)
1214 {
1215         int ret = MM_ERROR_NONE;
1216         int state = MM_CAMCORDER_STATE_NONE;
1217         int state_FROM = MM_CAMCORDER_STATE_READY;
1218         int state_TO = MM_CAMCORDER_STATE_NULL;
1219         ASM_resource_t mm_resource = ASM_RESOURCE_NONE;
1220
1221         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1222
1223         _mmcam_dbg_log("");
1224
1225         if (!hcamcorder) {
1226                 _mmcam_dbg_err("Not initialized");
1227                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
1228                 return ret;
1229         }
1230
1231         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1232                 _mmcam_dbg_err("Another command is running.");
1233                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
1234                 goto _ERR_CAMCORDER_CMD_PRECON;
1235         }
1236
1237         state = _mmcamcorder_get_state(handle);
1238         if (state != state_FROM) {
1239                 _mmcam_dbg_err("Wrong state(%d)", state);
1240                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
1241                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1242         }
1243
1244         /* Release SubContext */
1245         if (hcamcorder->sub_context) {
1246                 /* destroy pipeline */
1247                 _mmcamcorder_destroy_pipeline(handle, hcamcorder->type);
1248                 /* Deallocate SubContext */
1249                 _mmcamcorder_dealloc_subcontext(hcamcorder->sub_context);
1250                 hcamcorder->sub_context = NULL;
1251         }
1252
1253         /* Deinitialize main context member */
1254
1255         hcamcorder->command = NULL;
1256
1257         /* check who calls unrealize. it's no need to set ASM state if caller is ASM */
1258         if (hcamcorder->state_change_by_system != _MMCAMCORDER_STATE_CHANGE_BY_ASM) {
1259                 if (hcamcorder->asm_register) {
1260                         mm_resource = ASM_RESOURCE_NONE;
1261
1262                         switch (hcamcorder->type) {
1263                         case MM_CAMCORDER_MODE_AUDIO:
1264                                 mm_resource = ASM_RESOURCE_NONE;
1265                                 break;
1266                         case MM_CAMCORDER_MODE_VIDEO_CAPTURE:
1267                         default:
1268                                 mm_resource = ASM_RESOURCE_CAMERA | ASM_RESOURCE_VIDEO_OVERLAY | ASM_RESOURCE_HW_ENCODER;
1269                                 break;
1270                         }
1271
1272                         /* STOP session */
1273                         if (!ASM_set_sound_state(hcamcorder->asm_handle, hcamcorder->asm_event_type,
1274                                                  ASM_STATE_STOP, mm_resource, &ret)) {
1275                                 _mmcam_dbg_err("Set ASM state to STOP failed 0x%x", ret);
1276                         }
1277                 }
1278         }
1279
1280         /* set camera state to vconf key */
1281         if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
1282                 int vconf_camera_state = 0;
1283
1284                 /* get current camera state of vconf key */
1285                 vconf_get_int(VCONFKEY_CAMERA_STATE, &vconf_camera_state);
1286                 vconf_set_int(VCONFKEY_CAMERA_STATE, VCONFKEY_CAMERA_STATE_NULL);
1287
1288                 _mmcam_dbg_log("VCONFKEY_CAMERA_STATE prev %d -> cur %d",
1289                                vconf_camera_state, VCONFKEY_CAMERA_STATE_NULL);
1290         } else {
1291                 int vconf_recorder_state = 0;
1292
1293                 /* get current recorder state of vconf key */
1294                 vconf_get_int(VCONFKEY_RECORDER_STATE, &vconf_recorder_state);
1295                 vconf_set_int(VCONFKEY_RECORDER_STATE, VCONFKEY_RECORDER_STATE_NULL);
1296
1297                 _mmcam_dbg_log("VCONFKEY_RECORDER_STATE prev %d -> cur %d",
1298                                vconf_recorder_state, VCONFKEY_RECORDER_STATE_NULL);
1299         }
1300
1301         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1302
1303         _mmcamcorder_set_state(handle, state_TO);
1304
1305         return MM_ERROR_NONE;
1306
1307 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
1308         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1309
1310 _ERR_CAMCORDER_CMD_PRECON:
1311         /* send message */
1312         _mmcam_dbg_err("Unrealize fail (type %d, state %d, ret %x)",
1313                        hcamcorder->type, state, ret);
1314
1315         return ret;
1316 }
1317
1318 int _mmcamcorder_start(MMHandleType handle)
1319 {
1320         int ret = MM_ERROR_NONE;
1321         int state = MM_CAMCORDER_STATE_NONE;
1322         int state_FROM = MM_CAMCORDER_STATE_READY;
1323         int state_TO =MM_CAMCORDER_STATE_PREPARE;
1324
1325         _MMCamcorderSubContext *sc = NULL;
1326         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1327
1328         _mmcam_dbg_log("");
1329
1330         if (!hcamcorder) {
1331                 _mmcam_dbg_err("Not initialized");
1332                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
1333                 return ret;
1334         }
1335
1336         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1337         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1338
1339         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1340                 _mmcam_dbg_err("Another command is running.");
1341                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
1342                 goto _ERR_CAMCORDER_CMD_PRECON;
1343         }
1344
1345         state = _mmcamcorder_get_state(handle);
1346         if (state != state_FROM) {
1347                 _mmcam_dbg_err("Wrong state(%d)", state);
1348                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
1349                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1350         }
1351
1352         /* initialize error code */
1353         hcamcorder->error_code = MM_ERROR_NONE;
1354
1355         /* set attributes related sensor */
1356         if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
1357                 _mmcamcorder_set_attribute_to_camsensor(handle);
1358         }
1359
1360         ret = hcamcorder->command((MMHandleType)hcamcorder, _MMCamcorder_CMD_PREVIEW_START);
1361         if (ret != MM_ERROR_NONE) {
1362                 /* check internal error of gstreamer */
1363                 if (hcamcorder->error_code != MM_ERROR_NONE) {
1364                         ret = hcamcorder->error_code;
1365                         _mmcam_dbg_log("gstreamer error is occurred. return it %x", ret);
1366                 }
1367                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1368         }
1369
1370         _mmcamcorder_set_state(handle, state_TO);
1371
1372         if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
1373                 int vconf_camera_state = 0;
1374
1375                 /* check camera state of vconf key */
1376                 vconf_get_int(VCONFKEY_CAMERA_STATE, &vconf_camera_state);
1377
1378                 /* set camera state to vconf key */
1379                 vconf_set_int(VCONFKEY_CAMERA_STATE, VCONFKEY_CAMERA_STATE_PREVIEW);
1380
1381                 _mmcam_dbg_log("VCONFKEY_CAMERA_STATE prev %d -> cur %d",
1382                                vconf_camera_state, VCONFKEY_CAMERA_STATE_PREVIEW);
1383         }
1384
1385         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1386
1387         return MM_ERROR_NONE;
1388
1389 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
1390         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1391
1392 _ERR_CAMCORDER_CMD_PRECON:
1393         /* check internal error of gstreamer */
1394         if (hcamcorder->error_code != MM_ERROR_NONE) {
1395                 ret = hcamcorder->error_code;
1396                 hcamcorder->error_code = MM_ERROR_NONE;
1397
1398                 _mmcam_dbg_log("gstreamer error is occurred. return it %x", ret);
1399         }
1400
1401         _mmcam_dbg_err("Start fail (type %d, state %d, ret %x)",
1402                        hcamcorder->type, state, ret);
1403
1404         return ret;
1405 }
1406
1407 int _mmcamcorder_stop(MMHandleType handle)
1408 {
1409         int ret = MM_ERROR_NONE;
1410         int state = MM_CAMCORDER_STATE_NONE;
1411         int state_FROM = MM_CAMCORDER_STATE_PREPARE;
1412         int state_TO = MM_CAMCORDER_STATE_READY;
1413         int frame_rate = 0;
1414
1415         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1416
1417         _mmcam_dbg_log("");
1418
1419         if (!hcamcorder) {
1420                 _mmcam_dbg_err("Not initialized");
1421                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
1422                 return ret;
1423         }
1424
1425         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1426                 _mmcam_dbg_err("Another command is running.");
1427                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
1428                 goto _ERR_CAMCORDER_CMD_PRECON;
1429         }
1430
1431         state = _mmcamcorder_get_state(handle);
1432         if (state != state_FROM) {
1433                 _mmcam_dbg_err("Wrong state(%d)", state);
1434                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
1435                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1436         }
1437
1438         ret = hcamcorder->command((MMHandleType)hcamcorder, _MMCamcorder_CMD_PREVIEW_STOP);
1439         if (ret != MM_ERROR_NONE) {
1440                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1441         }
1442
1443         /* KPI : frame rate */
1444         frame_rate =_mmcamcorder_video_average_framerate(handle);
1445
1446         _mmcamcorder_set_state(handle, state_TO);
1447
1448         if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
1449                 int vconf_camera_state = 0;
1450
1451                 /* check camera state of vconf key */
1452                 vconf_get_int(VCONFKEY_CAMERA_STATE, &vconf_camera_state);
1453
1454                 /* set camera state to vconf key */
1455                 vconf_set_int(VCONFKEY_CAMERA_STATE, VCONFKEY_CAMERA_STATE_OPEN);
1456
1457                 _mmcam_dbg_log("VCONFKEY_CAMERA_STATE prev %d -> cur %d",
1458                                vconf_camera_state, VCONFKEY_CAMERA_STATE_OPEN);
1459         }
1460
1461         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1462
1463         return MM_ERROR_NONE;
1464
1465 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
1466         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1467
1468 _ERR_CAMCORDER_CMD_PRECON:
1469         /* send message */
1470         _mmcam_dbg_err("Stop fail (type %d, state %d, ret %x)",
1471                        hcamcorder->type, state, ret);
1472
1473         return ret;
1474 }
1475
1476
1477 int _mmcamcorder_capture_start(MMHandleType handle)
1478 {
1479         int ret = MM_ERROR_NONE;
1480         int state = MM_CAMCORDER_STATE_NONE;
1481         int state_FROM_0 = MM_CAMCORDER_STATE_PREPARE;
1482         int state_FROM_1 = MM_CAMCORDER_STATE_RECORDING;
1483         int state_FROM_2 = MM_CAMCORDER_STATE_PAUSED;
1484         int state_TO = MM_CAMCORDER_STATE_CAPTURING;
1485
1486         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1487
1488         _mmcam_dbg_log("");
1489
1490         if (!hcamcorder) {
1491                 _mmcam_dbg_err("Not initialized");
1492                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
1493                 return ret;
1494         }
1495
1496         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1497                 _mmcam_dbg_err("Another command is running.");
1498                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
1499                 goto _ERR_CAMCORDER_CMD_PRECON;
1500         }
1501
1502         state = _mmcamcorder_get_state(handle);
1503         if (state != state_FROM_0 &&
1504             state != state_FROM_1 &&
1505             state != state_FROM_2) {
1506                 _mmcam_dbg_err("Wrong state(%d)", state);
1507                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
1508                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1509         }
1510
1511         /* Handle capture in recording case */
1512         if (state == state_FROM_1 || state == state_FROM_2) {
1513                 if (hcamcorder->capture_in_recording == TRUE) {
1514                         _mmcam_dbg_err("Capturing in recording (%d)", state);
1515                         ret = MM_ERROR_CAMCORDER_DEVICE_BUSY;
1516                         goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1517                 } else {
1518                         pthread_mutex_lock(&(hcamcorder->task_thread_lock));
1519                         if (hcamcorder->task_thread_state == _MMCAMCORDER_TASK_THREAD_STATE_NONE) {
1520                                 hcamcorder->capture_in_recording = TRUE;
1521                                 hcamcorder->task_thread_state = _MMCAMCORDER_TASK_THREAD_STATE_CHECK_CAPTURE_IN_RECORDING;
1522                                 _mmcam_dbg_log("send signal for capture in recording");
1523                                 pthread_cond_signal(&(hcamcorder->task_thread_cond));
1524                                 pthread_mutex_unlock(&(hcamcorder->task_thread_lock));
1525                         } else {
1526                                 _mmcam_dbg_err("task thread busy : %d", hcamcorder->task_thread_state);
1527                                 pthread_mutex_unlock(&(hcamcorder->task_thread_lock));
1528                                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
1529                                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1530                         }
1531                 }
1532         }
1533
1534         ret = hcamcorder->command((MMHandleType)hcamcorder, _MMCamcorder_CMD_CAPTURE);
1535         if (ret != MM_ERROR_NONE) {
1536                 goto _ERR_CAMCORDER_CMD;
1537         }
1538
1539         /* Do not change state when recording snapshot capture */
1540         if (state == state_FROM_0) {
1541                 _mmcamcorder_set_state(handle, state_TO);
1542         }
1543
1544         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1545
1546         /* Init break continuous shot attr */
1547         if (mm_camcorder_set_attributes(handle, NULL, "capture-break-cont-shot", 0, NULL) != MM_ERROR_NONE) {
1548                 _mmcam_dbg_warn("capture-break-cont-shot set 0 failed");
1549         }
1550
1551         return MM_ERROR_NONE;
1552
1553 _ERR_CAMCORDER_CMD:
1554         if (hcamcorder->capture_in_recording) {
1555                 hcamcorder->capture_in_recording = FALSE;
1556         }
1557
1558 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
1559         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1560
1561 _ERR_CAMCORDER_CMD_PRECON:
1562         /* send message */
1563         _mmcam_dbg_err("Capture start fail (type %d, state %d, ret %x)",
1564                        hcamcorder->type, state, ret);
1565
1566         return ret;
1567 }
1568
1569 int _mmcamcorder_capture_stop(MMHandleType handle)
1570 {
1571         int ret = MM_ERROR_NONE;
1572         int state = MM_CAMCORDER_STATE_NONE;
1573         int state_FROM = MM_CAMCORDER_STATE_CAPTURING;
1574         int state_TO = MM_CAMCORDER_STATE_PREPARE;
1575         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1576
1577         _mmcam_dbg_log("");
1578
1579         if (!hcamcorder) {
1580                 _mmcam_dbg_err("Not initialized");
1581                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
1582                 return ret;
1583         }
1584
1585         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1586                 _mmcam_dbg_err("Another command is running.");
1587                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
1588                 goto _ERR_CAMCORDER_CMD_PRECON;
1589         }
1590
1591         state = _mmcamcorder_get_state(handle);
1592         if (state != state_FROM) {
1593                 _mmcam_dbg_err("Wrong state(%d)", state);
1594                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
1595                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1596         }
1597
1598         ret = hcamcorder->command((MMHandleType)hcamcorder, _MMCamcorder_CMD_PREVIEW_START);
1599         if (ret != MM_ERROR_NONE) {
1600                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1601         }
1602
1603         _mmcamcorder_set_state(handle, state_TO);
1604
1605         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1606
1607         return MM_ERROR_NONE;
1608
1609 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
1610         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1611
1612 _ERR_CAMCORDER_CMD_PRECON:
1613         /* send message */
1614         _mmcam_dbg_err("Capture stop fail (type %d, state %d, ret %x)",
1615                        hcamcorder->type, state, ret);
1616
1617         return ret;
1618 }
1619
1620 int _mmcamcorder_record(MMHandleType handle)
1621 {
1622         int ret = MM_ERROR_NONE;
1623         int state = MM_CAMCORDER_STATE_NONE;
1624         int state_FROM1 = MM_CAMCORDER_STATE_PREPARE;
1625         int state_FROM2 = MM_CAMCORDER_STATE_PAUSED;
1626         int state_TO = MM_CAMCORDER_STATE_RECORDING;
1627
1628         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1629
1630         _mmcam_dbg_log("");
1631
1632         if (!hcamcorder) {
1633                 _mmcam_dbg_err("Not initialized");
1634                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
1635                 return ret;
1636         }
1637
1638         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1639                 _mmcam_dbg_err("Another command is running.");
1640                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
1641                 goto _ERR_CAMCORDER_CMD_PRECON;
1642         }
1643
1644         state = _mmcamcorder_get_state(handle);
1645         if (state != state_FROM1 && state != state_FROM2) {
1646                 _mmcam_dbg_err("Wrong state(%d)", state);
1647                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
1648                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1649         }
1650
1651         if (state == state_FROM1) {
1652                 /* initialize error code */
1653                 hcamcorder->error_code = MM_ERROR_NONE;
1654
1655                 /* update session information */
1656                 if (hcamcorder->asm_register == _MMCamcorder_ASM_SESSION_REGISTERED_BY_OUTSIDE ||
1657                     hcamcorder->asm_register == _MMCamcorder_ASM_SESSION_REGISTERED_INTERNALLY) {
1658                         ret = _mm_session_util_read_information(-1, &hcamcorder->asm_session_type, &hcamcorder->asm_session_options);
1659                         if (ret != MM_ERROR_NONE) {
1660                                 _mmcam_dbg_warn("_mm_session_util_read_information failed[%x]", ret);
1661                                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1662                         } else {
1663                                 if (hcamcorder->asm_session_type == MM_SESSION_TYPE_MEDIA_RECORD) {
1664                                         _mmcam_dbg_err("session was already registered to MEDIA_RECORD, could not process it..");
1665                                         ret = MM_ERROR_POLICY_INTERNAL;
1666                                         goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1667                                 } else {
1668                                         int asm_ret = MM_ERROR_NONE;
1669                                         _mmcam_dbg_log("session is not MEDIA_RECORD, update it to MEDIA_RECORD");
1670                                         hcamcorder->asm_session_type = MM_SESSION_TYPE_MEDIA_RECORD;
1671                                         asm_ret = _mm_session_util_write_information(-1, hcamcorder->asm_session_type, hcamcorder->asm_session_options);
1672                                         if (asm_ret != MM_ERROR_NONE) {
1673                                                 _mmcam_dbg_err("_mm_session_util_write_information() [type %d, options %x] failed[%x]",
1674                                                                hcamcorder->asm_session_type, hcamcorder->asm_session_options, asm_ret);
1675                                                 ret = MM_ERROR_POLICY_INTERNAL;
1676                                                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1677                                         }
1678                                 }
1679                         }
1680                 }
1681         } else {
1682                 _mmcam_dbg_warn("skip session check - NOW PASUED state");
1683         }
1684
1685         ret = hcamcorder->command((MMHandleType)hcamcorder, _MMCamcorder_CMD_RECORD);
1686         if (ret != MM_ERROR_NONE) {
1687                 /* check internal error of gstreamer */
1688                 if (hcamcorder->error_code != MM_ERROR_NONE) {
1689                         ret = hcamcorder->error_code;
1690                         _mmcam_dbg_log("gstreamer error is occurred. return it %x", ret);
1691                 }
1692
1693                 /* Rollback session to MEDIA */
1694                 if (hcamcorder->asm_register == _MMCamcorder_ASM_SESSION_REGISTERED_BY_OUTSIDE ||
1695                     hcamcorder->asm_register == _MMCamcorder_ASM_SESSION_REGISTERED_INTERNALLY) {
1696                         _mmcam_dbg_log("Rollback session to MEDIA");
1697                         int asm_ret = MM_ERROR_NONE;
1698                         hcamcorder->asm_session_type = MM_SESSION_TYPE_MEDIA;
1699                         asm_ret = _mm_session_util_write_information(-1, hcamcorder->asm_session_type, hcamcorder->asm_session_options);
1700                         if (asm_ret != MM_ERROR_NONE) {
1701                                 _mmcam_dbg_err("_mm_session_util_write_information() [type %d, options %x] failed[%x]",
1702                                                hcamcorder->asm_session_type, hcamcorder->asm_session_options, asm_ret);
1703                         }
1704                 }
1705
1706                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1707         }
1708
1709         _mmcamcorder_set_state(handle, state_TO);
1710
1711         /* set camera state to vconf key */
1712         if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
1713                 int vconf_camera_state = 0;
1714
1715                 /* get current camera state of vconf key */
1716                 vconf_get_int(VCONFKEY_CAMERA_STATE, &vconf_camera_state);
1717                 vconf_set_int(VCONFKEY_CAMERA_STATE, VCONFKEY_CAMERA_STATE_RECORDING);
1718
1719                 _mmcam_dbg_log("VCONFKEY_CAMERA_STATE prev %d -> cur %d",
1720                                vconf_camera_state, VCONFKEY_CAMERA_STATE_RECORDING);
1721         } else {
1722                 int vconf_recorder_state = 0;
1723
1724                 /* get current recorder state of vconf key */
1725                 vconf_get_int(VCONFKEY_RECORDER_STATE, &vconf_recorder_state);
1726                 vconf_set_int(VCONFKEY_RECORDER_STATE, VCONFKEY_RECORDER_STATE_RECORDING);
1727
1728                 _mmcam_dbg_log("VCONFKEY_RECORDER_STATE prev %d -> cur %d",
1729                                vconf_recorder_state, VCONFKEY_RECORDER_STATE_RECORDING);
1730         }
1731
1732         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1733
1734         return MM_ERROR_NONE;
1735
1736 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
1737         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1738
1739 _ERR_CAMCORDER_CMD_PRECON:
1740         /* check internal error of gstreamer */
1741         if (hcamcorder->error_code != MM_ERROR_NONE) {
1742                 ret = hcamcorder->error_code;
1743                 hcamcorder->error_code = MM_ERROR_NONE;
1744
1745                 _mmcam_dbg_log("gstreamer error is occurred. return it %x", ret);
1746         }
1747
1748         _mmcam_dbg_err("Record fail (type %d, state %d, ret %x)",
1749                        hcamcorder->type, state, ret);
1750
1751         return ret;
1752 }
1753
1754
1755 int _mmcamcorder_pause(MMHandleType handle)
1756 {
1757         int ret = MM_ERROR_NONE;
1758         int state = MM_CAMCORDER_STATE_NONE;
1759         int state_FROM = MM_CAMCORDER_STATE_RECORDING;
1760         int state_TO = MM_CAMCORDER_STATE_PAUSED;
1761
1762         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1763
1764         _mmcam_dbg_log("");
1765
1766         if (!hcamcorder) {
1767                 _mmcam_dbg_err("Not initialized");
1768                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
1769                 return ret;
1770         }
1771
1772         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1773                 _mmcam_dbg_err("Another command is running.");
1774                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
1775                 goto _ERR_CAMCORDER_CMD_PRECON;
1776         }
1777
1778         state = _mmcamcorder_get_state(handle);
1779         if (state != state_FROM) {
1780                 _mmcam_dbg_err("Wrong state(%d)", state);
1781                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
1782                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1783         }
1784
1785         ret = hcamcorder->command((MMHandleType)hcamcorder, _MMCamcorder_CMD_PAUSE);
1786         if (ret != MM_ERROR_NONE) {
1787                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1788         }
1789
1790         _mmcamcorder_set_state(handle, state_TO);
1791
1792         /* set camera state to vconf key */
1793         if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
1794                 int vconf_camera_state = 0;
1795
1796                 /* get current camera state of vconf key */
1797                 vconf_get_int(VCONFKEY_CAMERA_STATE, &vconf_camera_state);
1798                 vconf_set_int(VCONFKEY_CAMERA_STATE, VCONFKEY_CAMERA_STATE_RECORDING_PAUSE);
1799
1800                 _mmcam_dbg_log("VCONFKEY_CAMERA_STATE prev %d -> cur %d",
1801                                vconf_camera_state, VCONFKEY_CAMERA_STATE_RECORDING_PAUSE);
1802         } else {
1803                 int vconf_recorder_state = 0;
1804
1805                 /* get current recorder state of vconf key */
1806                 vconf_get_int(VCONFKEY_RECORDER_STATE, &vconf_recorder_state);
1807                 vconf_set_int(VCONFKEY_RECORDER_STATE, VCONFKEY_RECORDER_STATE_RECORDING_PAUSE);
1808
1809                 _mmcam_dbg_log("VCONFKEY_RECORDER_STATE prev %d -> cur %d",
1810                                vconf_recorder_state, VCONFKEY_RECORDER_STATE_RECORDING_PAUSE);
1811         }
1812
1813         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1814
1815         return MM_ERROR_NONE;
1816
1817 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
1818         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1819
1820 _ERR_CAMCORDER_CMD_PRECON:
1821         /* send message */
1822         _mmcam_dbg_err("Pause fail (type %d, state %d, ret %x)",
1823                        hcamcorder->type, state, ret);
1824
1825         return ret;
1826 }
1827
1828
1829 int _mmcamcorder_commit(MMHandleType handle)
1830 {
1831         int ret = MM_ERROR_NONE;
1832         int state = MM_CAMCORDER_STATE_NONE;
1833         int state_FROM1 = MM_CAMCORDER_STATE_RECORDING;
1834         int state_FROM2 = MM_CAMCORDER_STATE_PAUSED;
1835         int state_TO = MM_CAMCORDER_STATE_PREPARE;
1836
1837         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1838
1839         _mmcam_dbg_log("");
1840
1841         if (!hcamcorder) {
1842                 _mmcam_dbg_err("Not initialized");
1843                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
1844                 return ret;
1845         }
1846
1847         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1848                 _mmcam_dbg_err("Another command is running.");
1849                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
1850                 goto _ERR_CAMCORDER_CMD_PRECON;
1851         }
1852
1853         state = _mmcamcorder_get_state(handle);
1854         if (state != state_FROM1 && state != state_FROM2) {
1855                 _mmcam_dbg_err("Wrong state(%d)", state);
1856                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
1857                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1858         }
1859
1860         ret = hcamcorder->command((MMHandleType)hcamcorder, _MMCamcorder_CMD_COMMIT);
1861         if (ret != MM_ERROR_NONE) {
1862                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1863         }
1864
1865         /* set camera state to vconf key */
1866         if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
1867                 int vconf_camera_state = 0;
1868
1869                 /* get current camera state of vconf key */
1870                 vconf_get_int(VCONFKEY_CAMERA_STATE, &vconf_camera_state);
1871                 vconf_set_int(VCONFKEY_CAMERA_STATE, VCONFKEY_CAMERA_STATE_PREVIEW);
1872
1873                 _mmcam_dbg_log("VCONFKEY_CAMERA_STATE prev %d -> cur %d",
1874                                vconf_camera_state, VCONFKEY_CAMERA_STATE_PREVIEW);
1875         } else {
1876                 int vconf_recorder_state = 0;
1877
1878                 /* get current recorder state of vconf key */
1879                 vconf_get_int(VCONFKEY_RECORDER_STATE, &vconf_recorder_state);
1880                 vconf_set_int(VCONFKEY_RECORDER_STATE, VCONFKEY_RECORDER_STATE_CREATED);
1881
1882                 _mmcam_dbg_log("VCONFKEY_RECORDER_STATE prev %d -> cur %d",
1883                                vconf_recorder_state, VCONFKEY_RECORDER_STATE_CREATED);
1884         }
1885
1886         /* check who calls unrealize. it's no need to set ASM state if caller is ASM */
1887         if (hcamcorder->state_change_by_system != _MMCAMCORDER_STATE_CHANGE_BY_ASM) {
1888                 /* update session information */
1889                 if (hcamcorder->asm_register == _MMCamcorder_ASM_SESSION_REGISTERED_BY_OUTSIDE ||
1890                     hcamcorder->asm_register == _MMCamcorder_ASM_SESSION_REGISTERED_INTERNALLY) {
1891                         _mmcam_dbg_log("session was registered to MEDIA_RECORD, update it to MEDIA");
1892                         int asm_ret = MM_ERROR_NONE;
1893                         hcamcorder->asm_session_type = MM_SESSION_TYPE_MEDIA;
1894                         asm_ret = _mm_session_util_write_information(-1, hcamcorder->asm_session_type, hcamcorder->asm_session_options);
1895                         if (asm_ret != MM_ERROR_NONE) {
1896                                 _mmcam_dbg_err("_mm_session_util_write_information() [type %d, options %x] failed[%x]",
1897                                                hcamcorder->asm_session_type, hcamcorder->asm_session_options, asm_ret);
1898                         }
1899                 }
1900         }
1901
1902         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1903
1904         _mmcamcorder_set_state(handle,state_TO);
1905
1906         return MM_ERROR_NONE;
1907
1908 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
1909         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1910
1911 _ERR_CAMCORDER_CMD_PRECON:
1912         /* send message */
1913         _mmcam_dbg_err("Commit fail (type %d, state %d, ret %x)",
1914                        hcamcorder->type, state, ret);
1915
1916         return ret;
1917 }
1918
1919
1920 int _mmcamcorder_cancel(MMHandleType handle)
1921 {
1922         int ret = MM_ERROR_NONE;
1923         int state = MM_CAMCORDER_STATE_NONE;
1924         int state_FROM1 = MM_CAMCORDER_STATE_RECORDING;
1925         int state_FROM2 = MM_CAMCORDER_STATE_PAUSED;
1926         int state_TO = MM_CAMCORDER_STATE_PREPARE;
1927
1928         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1929
1930         _mmcam_dbg_log("");
1931
1932         if (!hcamcorder) {
1933                 _mmcam_dbg_err("Not initialized");
1934                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
1935                 return ret;
1936         }
1937
1938         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1939                 _mmcam_dbg_err("Another command is running.");
1940                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
1941                 goto _ERR_CAMCORDER_CMD_PRECON;
1942         }
1943
1944         state = _mmcamcorder_get_state(handle);
1945         if (state != state_FROM1 && state != state_FROM2) {
1946                 _mmcam_dbg_err("Wrong state(%d)", state);
1947                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
1948                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1949         }
1950
1951         ret = hcamcorder->command((MMHandleType)hcamcorder, _MMCamcorder_CMD_CANCEL);
1952         if (ret != MM_ERROR_NONE) {
1953                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1954         }
1955
1956         _mmcamcorder_set_state(handle, state_TO);
1957
1958         /* update session information */
1959         if (hcamcorder->asm_register == _MMCamcorder_ASM_SESSION_REGISTERED_BY_OUTSIDE ||
1960             hcamcorder->asm_register == _MMCamcorder_ASM_SESSION_REGISTERED_INTERNALLY) {
1961                 _mmcam_dbg_log("session was registered to MEDIA_RECORD, update it to MEDIA");
1962                 int asm_ret = MM_ERROR_NONE;
1963                 hcamcorder->asm_session_type = MM_SESSION_TYPE_MEDIA;
1964                 asm_ret = _mm_session_util_write_information(-1, hcamcorder->asm_session_type, hcamcorder->asm_session_options);
1965                 if (asm_ret != MM_ERROR_NONE) {
1966                         _mmcam_dbg_err("_mm_session_util_write_information() [type %d, options %x] failed[%x]",
1967                                        hcamcorder->asm_session_type, hcamcorder->asm_session_options, asm_ret);
1968                 }
1969         }
1970
1971         /* set camera state to vconf key */
1972         if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
1973                 int vconf_camera_state = 0;
1974
1975                 /* get current camera state of vconf key */
1976                 vconf_get_int(VCONFKEY_CAMERA_STATE, &vconf_camera_state);
1977                 vconf_set_int(VCONFKEY_CAMERA_STATE, VCONFKEY_CAMERA_STATE_PREVIEW);
1978
1979                 _mmcam_dbg_log("VCONFKEY_CAMERA_STATE prev %d -> cur %d",
1980                                vconf_camera_state, VCONFKEY_CAMERA_STATE_PREVIEW);
1981         } else {
1982                 int vconf_recorder_state = 0;
1983
1984                 /* get current recorder state of vconf key */
1985                 vconf_get_int(VCONFKEY_RECORDER_STATE, &vconf_recorder_state);
1986                 vconf_set_int(VCONFKEY_RECORDER_STATE, VCONFKEY_RECORDER_STATE_CREATED);
1987
1988                 _mmcam_dbg_log("VCONFKEY_RECORDER_STATE prev %d -> cur %d",
1989                                vconf_recorder_state, VCONFKEY_RECORDER_STATE_CREATED);
1990         }
1991
1992         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1993
1994         return MM_ERROR_NONE;
1995
1996 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
1997         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1998
1999 _ERR_CAMCORDER_CMD_PRECON:
2000         /* send message */
2001         _mmcam_dbg_err("Cancel fail (type %d, state %d, ret %x)",
2002                        hcamcorder->type, state, ret);
2003
2004         return ret;
2005 }
2006 /* } Internal command functions */
2007
2008
2009 int _mmcamcorder_commit_async_end(MMHandleType handle)
2010 {
2011         _mmcam_dbg_log("");
2012
2013         _mmcam_dbg_warn("_mmcamcorder_commit_async_end : MM_CAMCORDER_STATE_PREPARE");
2014         _mmcamcorder_set_state(handle, MM_CAMCORDER_STATE_PREPARE);
2015
2016         return MM_ERROR_NONE;
2017 }
2018
2019
2020 int _mmcamcorder_set_message_callback(MMHandleType handle, MMMessageCallback callback, void *user_data)
2021 {
2022         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
2023
2024         _mmcam_dbg_log("%p", hcamcorder);
2025
2026         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2027
2028         if (callback == NULL) {
2029                 _mmcam_dbg_warn("Message Callback is disabled, because application sets it to NULL");
2030         }
2031
2032         if (!_MMCAMCORDER_TRYLOCK_MESSAGE_CALLBACK(hcamcorder)) {
2033                 _mmcam_dbg_warn("Application's message callback is running now");
2034                 return MM_ERROR_CAMCORDER_INVALID_CONDITION;
2035         }
2036
2037         /* set message callback to message handle */
2038         hcamcorder->msg_cb = callback;
2039         hcamcorder->msg_cb_param = user_data;
2040
2041         _MMCAMCORDER_UNLOCK_MESSAGE_CALLBACK(hcamcorder);
2042
2043         return MM_ERROR_NONE;
2044 }
2045
2046
2047 int _mmcamcorder_set_video_stream_callback(MMHandleType handle, mm_camcorder_video_stream_callback callback, void *user_data)
2048 {
2049         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
2050
2051         /*_mmcam_dbg_log("");*/
2052
2053         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2054
2055         if (callback == NULL) {
2056                 _mmcam_dbg_warn("Video Stream Callback is disabled, because application sets it to NULL");
2057         }
2058
2059         if (!_MMCAMCORDER_TRYLOCK_VSTREAM_CALLBACK(hcamcorder)) {
2060                 _mmcam_dbg_warn("Application's video stream callback is running now");
2061                 return MM_ERROR_CAMCORDER_INVALID_CONDITION;
2062         }
2063
2064         hcamcorder->vstream_cb = callback;
2065         hcamcorder->vstream_cb_param = user_data;
2066
2067         _MMCAMCORDER_UNLOCK_VSTREAM_CALLBACK(hcamcorder);
2068
2069         return MM_ERROR_NONE;
2070 }
2071
2072
2073 int _mmcamcorder_set_video_frame_render_error_callback(MMHandleType handle, mm_camcorder_video_frame_render_error_callback callback, void *user_data)
2074 {
2075         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
2076
2077         /*_mmcam_dbg_log("");*/
2078
2079         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2080
2081         if (callback == NULL) {
2082                 _mmcam_dbg_warn("Video Frame Rencoder Error Callback is disabled, because application sets it to NULL");
2083         }
2084
2085         hcamcorder->render_error_cb = callback;
2086         hcamcorder->render_error_cb_user_param = user_data;
2087
2088         return MM_ERROR_NONE;
2089 }
2090
2091
2092 int _mmcamcorder_set_audio_stream_callback(MMHandleType handle, mm_camcorder_audio_stream_callback callback, void *user_data)
2093 {
2094         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
2095
2096         _mmcam_dbg_log("");
2097
2098         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2099
2100         if (callback == NULL) {
2101                 _mmcam_dbg_warn("Audio Stream Callback is disabled, because application sets it to NULL");
2102         }
2103
2104         if (!_MMCAMCORDER_TRYLOCK_ASTREAM_CALLBACK(hcamcorder)) {
2105                 _mmcam_dbg_warn("Application's audio stream callback is running now");
2106                 return MM_ERROR_CAMCORDER_INVALID_CONDITION;
2107         }
2108
2109         hcamcorder->astream_cb = callback;
2110         hcamcorder->astream_cb_param = user_data;
2111
2112         _MMCAMCORDER_UNLOCK_ASTREAM_CALLBACK(hcamcorder);
2113
2114         return MM_ERROR_NONE;
2115 }
2116
2117
2118 int _mmcamcorder_set_video_capture_callback(MMHandleType handle, mm_camcorder_video_capture_callback callback, void *user_data)
2119 {
2120         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
2121
2122         _mmcam_dbg_log("");
2123
2124         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2125
2126         if (callback == NULL) {
2127                 _mmcam_dbg_warn("Video Capture Callback is disabled, because application sets it to NULLL");
2128         }
2129
2130         if (!_MMCAMCORDER_TRYLOCK_VCAPTURE_CALLBACK(hcamcorder)) {
2131                 _mmcam_dbg_warn("Application's video capture callback is running now");
2132                 return MM_ERROR_CAMCORDER_INVALID_CONDITION;
2133         }
2134
2135         hcamcorder->vcapture_cb = callback;
2136         hcamcorder->vcapture_cb_param = user_data;
2137
2138         _MMCAMCORDER_UNLOCK_VCAPTURE_CALLBACK(hcamcorder);
2139
2140         return MM_ERROR_NONE;
2141 }
2142
2143 int _mmcamcorder_get_current_state(MMHandleType handle)
2144 {
2145         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
2146
2147         _mmcam_dbg_log("");
2148
2149         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2150
2151         return _mmcamcorder_get_state(handle);
2152 }
2153
2154 int _mmcamcorder_init_focusing(MMHandleType handle)
2155 {
2156         int ret = TRUE;
2157         int state = MM_CAMCORDER_STATE_NONE;
2158         int focus_mode = MM_CAMCORDER_FOCUS_MODE_NONE;
2159         int af_range = MM_CAMCORDER_AUTO_FOCUS_NORMAL;
2160         int sensor_focus_mode = 0;
2161         int sensor_af_range = 0;
2162         int current_focus_mode = 0;
2163         int current_af_range = 0;
2164         mmf_camcorder_t *hcamcorder = NULL;
2165         _MMCamcorderSubContext *sc = NULL;
2166         GstCameraControl *control = NULL;
2167
2168         _mmcam_dbg_log("");
2169
2170         hcamcorder = MMF_CAMCORDER(handle);
2171         mmf_return_val_if_fail(handle, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2172
2173         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
2174         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2175
2176         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
2177                 _mmcam_dbg_err("Another command is running.");
2178                 return MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
2179         }
2180
2181         state = _mmcamcorder_get_state(handle);
2182
2183         if (state == MM_CAMCORDER_STATE_CAPTURING ||
2184             state < MM_CAMCORDER_STATE_PREPARE) {
2185                 _mmcam_dbg_err( "Not proper state. state[%d]", state );
2186                 _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
2187                 return MM_ERROR_CAMCORDER_INVALID_STATE;
2188         }
2189
2190         if (!GST_IS_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst)) {
2191                 _mmcam_dbg_log("Can't cast Video source into camera control.");
2192                 _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
2193                 return MM_ERROR_NONE;
2194         }
2195
2196         control = GST_CAMERA_CONTROL (sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
2197         if (control == NULL) {
2198                 _mmcam_dbg_err("cast CAMERA_CONTROL failed");
2199                 _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
2200                 return MM_ERROR_CAMCORDER_INTERNAL;
2201         }
2202
2203         ret = gst_camera_control_stop_auto_focus(control);
2204         if (!ret) {
2205                 _mmcam_dbg_err("Auto focusing stop fail.");
2206                 _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
2207                 return MM_ERROR_CAMCORDER_DEVICE_IO;
2208         }
2209
2210         /* Initialize lens position */
2211         mm_camcorder_get_attributes(handle, NULL,
2212                                     MMCAM_CAMERA_FOCUS_MODE, &focus_mode,
2213                                     MMCAM_CAMERA_AF_SCAN_RANGE, &af_range,
2214                                     NULL);
2215         sensor_af_range = _mmcamcorder_convert_msl_to_sensor(handle, MM_CAM_CAMERA_AF_SCAN_RANGE, af_range);
2216         sensor_focus_mode = _mmcamcorder_convert_msl_to_sensor(handle, MM_CAM_CAMERA_FOCUS_MODE, focus_mode);
2217
2218         gst_camera_control_get_focus(control, &current_focus_mode, &current_af_range);
2219
2220         if (current_focus_mode != sensor_focus_mode ||
2221             current_af_range != sensor_af_range) {
2222                 ret = gst_camera_control_set_focus(control, sensor_focus_mode, sensor_af_range);
2223         } else {
2224                 _mmcam_dbg_log("No need to init FOCUS [mode:%d, range:%d]", focus_mode, af_range );
2225                 ret = TRUE;
2226         }
2227
2228         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
2229
2230         if (ret) {
2231                 _mmcam_dbg_log("Lens init success.");
2232                 return MM_ERROR_NONE;
2233         } else {
2234                 _mmcam_dbg_err("Lens init fail.");
2235                 return MM_ERROR_CAMCORDER_DEVICE_IO;
2236         }
2237 }
2238
2239 int _mmcamcorder_adjust_focus(MMHandleType handle, int direction)
2240 {
2241         int state;
2242         int focus_mode = MM_CAMCORDER_FOCUS_MODE_NONE;
2243         int ret = MM_ERROR_UNKNOWN;
2244         char *err_attr_name = NULL;
2245
2246         mmf_return_val_if_fail(handle, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2247         mmf_return_val_if_fail(direction, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
2248
2249         /*_mmcam_dbg_log("");*/
2250
2251         if (!_MMCAMCORDER_TRYLOCK_CMD(handle)) {
2252                 _mmcam_dbg_err("Another command is running.");
2253                 return MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
2254         }
2255
2256         state = _mmcamcorder_get_state(handle);
2257         if (state == MM_CAMCORDER_STATE_CAPTURING ||
2258             state < MM_CAMCORDER_STATE_PREPARE) {
2259                 _mmcam_dbg_err("Not proper state. state[%d]", state);
2260                 _MMCAMCORDER_UNLOCK_CMD(handle);
2261                 return MM_ERROR_CAMCORDER_INVALID_STATE;
2262         }
2263
2264         /* TODO : call a auto or manual focus function */
2265         ret = mm_camcorder_get_attributes(handle, &err_attr_name,
2266                                           MMCAM_CAMERA_FOCUS_MODE, &focus_mode,
2267                                           NULL);
2268         if (ret != MM_ERROR_NONE) {
2269                 _mmcam_dbg_warn("Get focus-mode fail. (%s:%x)", err_attr_name, ret);
2270                 SAFE_FREE (err_attr_name);
2271                 _MMCAMCORDER_UNLOCK_CMD(handle);
2272                 return ret;
2273         }
2274
2275         if (focus_mode == MM_CAMCORDER_FOCUS_MODE_MANUAL) {
2276                 ret = _mmcamcorder_adjust_manual_focus(handle, direction);
2277         } else if (focus_mode == MM_CAMCORDER_FOCUS_MODE_AUTO ||
2278                    focus_mode == MM_CAMCORDER_FOCUS_MODE_TOUCH_AUTO ||
2279                    focus_mode == MM_CAMCORDER_FOCUS_MODE_CONTINUOUS) {
2280                 ret = _mmcamcorder_adjust_auto_focus(handle);
2281         } else {
2282                 _mmcam_dbg_err("It doesn't adjust focus. Focusing mode(%d)", focus_mode);
2283                 ret = MM_ERROR_CAMCORDER_NOT_SUPPORTED;
2284         }
2285
2286         _MMCAMCORDER_UNLOCK_CMD(handle);
2287
2288         return ret;
2289 }
2290
2291 int _mmcamcorder_adjust_manual_focus(MMHandleType handle, int direction)
2292 {
2293         int max_level = 0;
2294         int min_level = 0;
2295         int cur_level = 0;
2296         int focus_level = 0;
2297         float unit_level = 0;
2298         GstCameraControl *control = NULL;
2299         _MMCamcorderSubContext *sc = NULL;
2300         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
2301
2302         _mmcam_dbg_log("");
2303
2304         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2305         mmf_return_val_if_fail(_MMFCAMCORDER_FOCUS_TOTAL_LEVEL != 1, MM_ERROR_CAMCORDER_NOT_SUPPORTED);
2306         mmf_return_val_if_fail((direction >= MM_CAMCORDER_MF_LENS_DIR_FORWARD) &&
2307                                (direction <= MM_CAMCORDER_MF_LENS_DIR_BACKWARD),
2308                                MM_ERROR_CAMCORDER_INVALID_ARGUMENT );
2309
2310         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
2311         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2312
2313         if (!GST_IS_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst)) {
2314                 _mmcam_dbg_log("Can't cast Video source into camera control.");
2315                 return MM_ERROR_NONE;
2316         }
2317
2318         control = GST_CAMERA_CONTROL (sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
2319         if (control == NULL) {
2320                 _mmcam_dbg_err("cast CAMERA_CONTROL failed");
2321                 return MM_ERROR_CAMCORDER_INTERNAL;
2322         }
2323
2324         /* TODO : get max, min level */
2325         if (max_level - min_level + 1 < _MMFCAMCORDER_FOCUS_TOTAL_LEVEL) {
2326                 _mmcam_dbg_warn("Total level  of manual focus of MMF is greater than that of the camera driver.");
2327         }
2328
2329         unit_level = ((float)max_level - (float)min_level)/(float)(_MMFCAMCORDER_FOCUS_TOTAL_LEVEL - 1);
2330
2331         if (!gst_camera_control_get_focus_level(control, &cur_level)) {
2332                 _mmcam_dbg_err("Can't get current level of manual focus.");
2333                 return MM_ERROR_CAMCORDER_DEVICE_IO;
2334         }
2335
2336         //TODO : adjust unit level value
2337         if (direction == MM_CAMCORDER_MF_LENS_DIR_FORWARD) {
2338                 focus_level = cur_level + unit_level;
2339         } else if (direction == MM_CAMCORDER_MF_LENS_DIR_BACKWARD) {
2340                 focus_level = cur_level - unit_level;
2341         }
2342
2343         if (focus_level > max_level) {
2344                 focus_level = max_level;
2345         } else if (focus_level < min_level) {
2346                 focus_level = min_level;
2347         }
2348
2349         if (!gst_camera_control_set_focus_level(control, focus_level)) {
2350                 _mmcam_dbg_err("Manual focusing fail.");
2351                 return MM_ERROR_CAMCORDER_DEVICE_IO;
2352         }
2353
2354         return MM_ERROR_NONE;
2355 }
2356
2357
2358 int _mmcamcorder_adjust_auto_focus(MMHandleType handle)
2359 {
2360         gboolean ret;
2361         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
2362         GstCameraControl *control = NULL;
2363         _MMCamcorderSubContext *sc = NULL;
2364
2365         mmf_return_val_if_fail(handle, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2366
2367         /*_mmcam_dbg_log("");*/
2368
2369         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
2370
2371         if (!GST_IS_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst)) {
2372                 _mmcam_dbg_log("Can't cast Video source into camera control.");
2373                 return MM_ERROR_NONE;
2374         }
2375
2376         control = GST_CAMERA_CONTROL (sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
2377         if (control) {
2378                 /* Start AF */
2379                 ret = gst_camera_control_start_auto_focus(control);
2380         } else {
2381                 _mmcam_dbg_err("cast CAMERA_CONTROL failed");
2382                 ret = FALSE;
2383         }
2384
2385         if (ret) {
2386                 _mmcam_dbg_log("Auto focusing start success.");
2387                 return MM_ERROR_NONE;
2388         } else {
2389                 _mmcam_dbg_err("Auto focusing start fail.");
2390                 return MM_ERROR_CAMCORDER_DEVICE_IO;
2391         }
2392 }
2393
2394 int _mmcamcorder_stop_focusing(MMHandleType handle)
2395 {
2396         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
2397         _MMCamcorderSubContext *sc = NULL;
2398
2399         int ret, state;
2400         GstCameraControl *control = NULL;
2401
2402         mmf_return_val_if_fail(handle, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
2403
2404         /*_mmcam_dbg_log("");*/
2405
2406         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
2407
2408         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
2409                 _mmcam_dbg_err("Another command is running.");
2410                 return MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
2411         }
2412
2413         state = _mmcamcorder_get_state(handle);
2414         if (state == MM_CAMCORDER_STATE_CAPTURING ||
2415             state < MM_CAMCORDER_STATE_PREPARE) {
2416                 _mmcam_dbg_err( "Not proper state. state[%d]", state );
2417                 _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
2418                 return MM_ERROR_CAMCORDER_INVALID_STATE;
2419         }
2420
2421         if (!GST_IS_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst)) {
2422                 _mmcam_dbg_log("Can't cast Video source into camera control.");
2423                 _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
2424                 return MM_ERROR_NONE;
2425         }
2426
2427         control = GST_CAMERA_CONTROL(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
2428         if (control) {
2429                 ret = gst_camera_control_stop_auto_focus(control);
2430         } else {
2431                 _mmcam_dbg_err("cast CAMERA_CONTROL failed");
2432                 ret = FALSE;
2433         }
2434
2435         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
2436
2437         if (ret) {
2438                 _mmcam_dbg_log("Auto focusing stop success.");
2439                 return MM_ERROR_NONE;
2440         } else {
2441                 _mmcam_dbg_err("Auto focusing stop fail.");
2442                 return MM_ERROR_CAMCORDER_DEVICE_IO;
2443         }
2444 }
2445
2446
2447 /*-----------------------------------------------
2448 |         CAMCORDER INTERNAL LOCAL              |
2449 -----------------------------------------------*/
2450 static gboolean
2451 __mmcamcorder_gstreamer_init(camera_conf * conf)
2452 {
2453         static const int max_argc = 10;
2454         int i = 0;
2455         int cnt_str = 0;
2456         gint *argc = NULL;
2457         gchar **argv = NULL;
2458         GError *err = NULL;
2459         gboolean ret = FALSE;
2460         type_string_array *GSTInitOption = NULL;
2461
2462         mmf_return_val_if_fail(conf, FALSE);
2463
2464         _mmcam_dbg_log("");
2465
2466         /* alloc */
2467         argc = malloc(sizeof(int));
2468         argv = malloc(sizeof(gchar *) * max_argc);
2469
2470         if (!argc || !argv) {
2471                 goto ERROR;
2472         }
2473
2474         memset(argv, 0, sizeof(gchar *) * max_argc);
2475
2476         /* add initial */
2477         *argc = 1;
2478         argv[0] = g_strdup("mmcamcorder");
2479
2480         /* add gst_param */
2481         _mmcamcorder_conf_get_value_string_array(conf,
2482                                                  CONFIGURE_CATEGORY_MAIN_GENERAL,
2483                                                  "GSTInitOption",
2484                                                  &GSTInitOption);
2485         if (GSTInitOption != NULL && GSTInitOption->value) {
2486                 cnt_str = GSTInitOption->count;
2487                 for( ; *argc < max_argc && *argc <= cnt_str ; (*argc)++ )
2488                 {
2489                         argv[*argc] = g_strdup(GSTInitOption->value[(*argc)-1]);
2490                 }
2491         }
2492
2493         _mmcam_dbg_log("initializing gstreamer with following parameter[argc:%d]", *argc);
2494
2495         for (i = 0; i < *argc; i++) {
2496                 _mmcam_dbg_log("argv[%d] : %s", i, argv[i]);
2497         }
2498
2499         /* initializing gstreamer */
2500         ret = gst_init_check (argc, &argv, &err);
2501         if (!ret) {
2502                 _mmcam_dbg_err("Could not initialize GStreamer: %s ",
2503                                err ? err->message : "unknown error occurred");
2504                 if (err) {
2505                         g_error_free (err);
2506                 }
2507         }
2508
2509         /* release */
2510         for (i = 0; i < *argc; i++) {
2511                 if (argv[i]) {
2512                         free(argv[i]);
2513                         argv[i] = NULL;
2514                 }
2515         }
2516
2517         if (argv) {
2518                 free(argv);
2519                 argv = NULL;
2520         }
2521
2522         if (argc) {
2523                 free(argc);
2524                 argc = NULL;
2525         }
2526
2527         return ret;
2528
2529 ERROR:
2530         _mmcam_dbg_err("failed to initialize gstreamer");
2531
2532         if (argv) {
2533                 free(argv);
2534                 argv = NULL;
2535         }
2536
2537         if (argc) {
2538                 free(argc);
2539                 argc = NULL;
2540         }
2541
2542         return FALSE;
2543 }
2544
2545
2546 int _mmcamcorder_get_state(MMHandleType handle)
2547 {
2548         int state;
2549         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
2550
2551         mmf_return_val_if_fail(hcamcorder, -1);
2552
2553         _MMCAMCORDER_LOCK_STATE(handle);
2554
2555         state = hcamcorder->state;
2556         /*_mmcam_dbg_log("state=%d",state);*/
2557
2558         _MMCAMCORDER_UNLOCK_STATE(handle);
2559
2560         return state;
2561 }
2562
2563
2564 void _mmcamcorder_set_state(MMHandleType handle, int state)
2565 {
2566         int old_state;
2567         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
2568         _MMCamcorderMsgItem msg;
2569
2570         mmf_return_if_fail(hcamcorder);
2571
2572         /*_mmcam_dbg_log("");*/
2573
2574         _MMCAMCORDER_LOCK_STATE(handle);
2575
2576         old_state = hcamcorder->state;
2577         if(old_state != state) {
2578                 hcamcorder->state = state;
2579                 hcamcorder->target_state = state;
2580
2581                 _mmcam_dbg_log("set state[%d] and send state-changed message", state);
2582
2583                 /* To discern who changes the state */
2584                 switch (hcamcorder->state_change_by_system) {
2585                 case _MMCAMCORDER_STATE_CHANGE_BY_ASM:
2586                         msg.id = MM_MESSAGE_CAMCORDER_STATE_CHANGED_BY_ASM;
2587                         msg.param.state.code = hcamcorder->asm_event_code;
2588                         break;
2589                 case _MMCAMCORDER_STATE_CHANGE_NORMAL:
2590                 default:
2591                         msg.id = MM_MESSAGE_CAMCORDER_STATE_CHANGED;
2592                         msg.param.state.code = MM_ERROR_NONE;
2593                         break;
2594                 }
2595
2596                 msg.param.state.previous = old_state;
2597                 msg.param.state.current = state;
2598
2599                 /*_mmcam_dbg_log("_mmcamcorder_send_message : msg : %p, id:%x", &msg, msg.id);*/
2600                 _mmcamcorder_send_message(handle, &msg);
2601         }
2602
2603         _MMCAMCORDER_UNLOCK_STATE(handle);
2604
2605         return;
2606 }
2607
2608
2609 int _mmcamcorder_get_async_state(MMHandleType handle)
2610 {
2611         int state;
2612         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
2613
2614         _MMCAMCORDER_LOCK_STATE(handle);
2615         state = hcamcorder->target_state;
2616
2617         _MMCAMCORDER_UNLOCK_STATE(handle);
2618
2619         return state;
2620 }
2621
2622
2623 _MMCamcorderSubContext *_mmcamcorder_alloc_subcontext(int type)
2624 {
2625         int i;
2626         _MMCamcorderSubContext *sc = NULL;
2627
2628         /*_mmcam_dbg_log("");*/
2629
2630         /* alloc container */
2631         sc = (_MMCamcorderSubContext *)malloc(sizeof(_MMCamcorderSubContext));
2632         mmf_return_val_if_fail(sc != NULL, NULL);
2633
2634         /* init members */
2635         memset(sc, 0x00, sizeof(_MMCamcorderSubContext));
2636
2637         sc->element_num = _MMCAMCORDER_PIPELINE_ELEMENT_NUM;
2638         sc->encode_element_num = _MMCAMCORDER_ENCODE_PIPELINE_ELEMENT_NUM;
2639
2640         /* alloc info for each mode */
2641         switch (type) {
2642         case MM_CAMCORDER_MODE_AUDIO:
2643                 sc->info_audio = malloc( sizeof(_MMCamcorderAudioInfo));
2644                 if(!sc->info_audio) {
2645                         _mmcam_dbg_err("Failed to alloc info structure");
2646                         goto ALLOC_SUBCONTEXT_FAILED;
2647                 }
2648                 memset(sc->info_audio, 0x00, sizeof(_MMCamcorderAudioInfo));
2649                 break;
2650         case MM_CAMCORDER_MODE_VIDEO_CAPTURE:
2651         default:
2652                 sc->info_image = malloc( sizeof(_MMCamcorderImageInfo));
2653                 if(!sc->info_image) {
2654                         _mmcam_dbg_err("Failed to alloc info structure");
2655                         goto ALLOC_SUBCONTEXT_FAILED;
2656                 }
2657                 memset(sc->info_image, 0x00, sizeof(_MMCamcorderImageInfo));
2658
2659                 /* init sound status */
2660                 sc->info_image->sound_status = _SOUND_STATUS_INIT;
2661
2662                 sc->info_video = malloc( sizeof(_MMCamcorderVideoInfo));
2663                 if(!sc->info_video) {
2664                         _mmcam_dbg_err("Failed to alloc info structure");
2665                         goto ALLOC_SUBCONTEXT_FAILED;
2666                 }
2667                 memset(sc->info_video, 0x00, sizeof(_MMCamcorderVideoInfo));
2668                 pthread_mutex_init(&(sc->info_video->size_check_lock), NULL);
2669                 break;
2670         }
2671
2672         /* alloc element array */
2673         sc->element = (_MMCamcorderGstElement *)malloc(sizeof(_MMCamcorderGstElement) * sc->element_num);
2674         if(!sc->element) {
2675                 _mmcam_dbg_err("Failed to alloc element structure");
2676                 goto ALLOC_SUBCONTEXT_FAILED;
2677         }
2678
2679         sc->encode_element = (_MMCamcorderGstElement *)malloc(sizeof(_MMCamcorderGstElement) * sc->encode_element_num);
2680         if(!sc->encode_element) {
2681                 _mmcam_dbg_err("Failed to alloc encode element structure");
2682                 goto ALLOC_SUBCONTEXT_FAILED;
2683         }
2684
2685         for (i = 0 ; i < sc->element_num ; i++) {
2686                 sc->element[i].id = _MMCAMCORDER_NONE;
2687                 sc->element[i].gst = NULL;
2688         }
2689
2690         for (i = 0 ; i < sc->encode_element_num ; i++) {
2691                 sc->encode_element[i].id = _MMCAMCORDER_NONE;
2692                 sc->encode_element[i].gst = NULL;
2693         }
2694
2695         sc->fourcc = 0x80000000;
2696         sc->cam_stability_count = 0;
2697         sc->drop_vframe = 0;
2698         sc->pass_first_vframe = 0;
2699         sc->is_modified_rate = FALSE;
2700
2701         return sc;
2702
2703 ALLOC_SUBCONTEXT_FAILED:
2704         if (sc) {
2705                 if (sc->info_audio) {
2706                         free(sc->info_audio);
2707                         sc->info_audio = NULL;
2708                 }
2709                 if (sc->info_image) {
2710                         free(sc->info_image);
2711                         sc->info_image = NULL;
2712                 }
2713                 if (sc->info_video) {
2714                         pthread_mutex_destroy(&(sc->info_video->size_check_lock));
2715                         free(sc->info_video);
2716                         sc->info_video = NULL;
2717                 }
2718                 if (sc->element) {
2719                         free(sc->element);
2720                         sc->element = NULL;
2721                 }
2722                 if (sc->encode_element) {
2723                         free(sc->encode_element);
2724                         sc->encode_element = NULL;
2725                 }
2726                 free(sc);
2727                 sc = NULL;
2728         }
2729
2730         return NULL;
2731 }
2732
2733
2734 void _mmcamcorder_dealloc_subcontext(_MMCamcorderSubContext *sc)
2735 {
2736         _mmcam_dbg_log("");
2737
2738         if (sc) {
2739                 if (sc->element) {
2740                         _mmcam_dbg_log("release element");
2741                         free(sc->element);
2742                         sc->element = NULL;
2743                 }
2744
2745                 if (sc->encode_element) {
2746                         _mmcam_dbg_log("release encode_element");
2747                         free(sc->encode_element);
2748                         sc->encode_element = NULL;
2749                 }
2750
2751                 if (sc->info_image) {
2752                         _mmcam_dbg_log("release info_image");
2753                         free(sc->info_image);
2754                         sc->info_image = NULL;
2755                 }
2756
2757                 if (sc->info_video) {
2758                         _mmcam_dbg_log("release info_video");
2759                         if (sc->info_video->filename) {
2760                                 free(sc->info_video->filename);
2761                                 sc->info_video->filename = NULL;
2762                         }
2763                         pthread_mutex_destroy(&(sc->info_video->size_check_lock));
2764                         free(sc->info_video);
2765                         sc->info_video = NULL;
2766                 }
2767
2768                 if (sc->info_audio) {
2769                         _mmcam_dbg_log("release info_audio");
2770                         if (sc->info_audio->filename) {
2771                                 free(sc->info_audio->filename);
2772                                 sc->info_audio->filename = NULL;
2773                         }
2774                         free(sc->info_audio);
2775                         sc->info_audio = NULL;
2776                 }
2777
2778                 free(sc);
2779                 sc = NULL;
2780         }
2781
2782         return;
2783 }
2784
2785
2786 int _mmcamcorder_set_functions(MMHandleType handle, int type)
2787 {
2788         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
2789
2790         /*_mmcam_dbg_log("");*/
2791
2792         switch (type) {
2793         case MM_CAMCORDER_MODE_AUDIO:
2794                 hcamcorder->command = _mmcamcorder_audio_command;
2795                 break;
2796         case MM_CAMCORDER_MODE_VIDEO_CAPTURE:
2797         default:
2798                 hcamcorder->command = _mmcamcorder_video_capture_command;
2799                 break;
2800         }
2801
2802         return MM_ERROR_NONE;
2803 }
2804
2805
2806 gboolean _mmcamcorder_pipeline_cb_message(GstBus *bus, GstMessage *message, gpointer data)
2807 {
2808         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(data);
2809         _MMCamcorderSubContext *sc = NULL;
2810
2811         mmf_return_val_if_fail(hcamcorder, FALSE);
2812         mmf_return_val_if_fail(message, FALSE);
2813         //_mmcam_dbg_log("message type=(%d)", GST_MESSAGE_TYPE(message));
2814
2815         switch (GST_MESSAGE_TYPE(message)) {
2816         case GST_MESSAGE_UNKNOWN:
2817                 _mmcam_dbg_log("GST_MESSAGE_UNKNOWN");
2818                 break;
2819         case GST_MESSAGE_EOS:
2820         {
2821                 _mmcam_dbg_log ("Got EOS from element \"%s\".",
2822                                 GST_STR_NULL(GST_ELEMENT_NAME(GST_MESSAGE_SRC(message))));
2823
2824                 sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
2825                 mmf_return_val_if_fail(sc, TRUE);
2826
2827                 if (hcamcorder->type != MM_CAMCORDER_MODE_AUDIO) {
2828                         mmf_return_val_if_fail(sc->info_video, TRUE);
2829                         if (sc->info_video->b_commiting) {
2830                                 _mmcamcorder_video_handle_eos((MMHandleType)hcamcorder);
2831                         }
2832                 } else {
2833                         mmf_return_val_if_fail(sc->info_audio, TRUE);
2834                         if (sc->info_audio->b_commiting) {
2835                                 _mmcamcorder_audio_handle_eos((MMHandleType)hcamcorder);
2836                         }
2837                 }
2838
2839                 sc->bget_eos = TRUE;
2840
2841                 break;
2842         }
2843         case GST_MESSAGE_ERROR:
2844         {
2845                 GError *err;
2846                 gchar *debug;
2847                 gst_message_parse_error(message, &err, &debug);
2848
2849                 _mmcam_dbg_err ("GSTERR: %s", err->message);
2850                 _mmcam_dbg_err ("Error Debug: %s", debug);
2851
2852                 __mmcamcorder_handle_gst_error((MMHandleType)hcamcorder, message, err);
2853
2854                 g_error_free (err);
2855                 g_free (debug);
2856                 break;
2857         }
2858         case GST_MESSAGE_WARNING:
2859         {
2860                 GError *err;
2861                 gchar *debug;
2862                 gst_message_parse_warning (message, &err, &debug);
2863
2864                 _mmcam_dbg_warn("GSTWARN: %s", err->message);
2865
2866                 __mmcamcorder_handle_gst_warning((MMHandleType)hcamcorder, message, err);
2867
2868                 g_error_free (err);
2869                 g_free (debug);
2870                 break;
2871         }
2872         case GST_MESSAGE_INFO:
2873                 _mmcam_dbg_log("GST_MESSAGE_INFO");
2874                 break;
2875         case GST_MESSAGE_TAG:
2876                 _mmcam_dbg_log("GST_MESSAGE_TAG");
2877                 break;
2878         case GST_MESSAGE_BUFFERING:
2879                 _mmcam_dbg_log("GST_MESSAGE_BUFFERING");
2880                 break;
2881         case GST_MESSAGE_STATE_CHANGED:
2882         {
2883                 const GValue *vnewstate;
2884                 GstState newstate;
2885                 GstElement *pipeline = NULL;
2886
2887                 sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
2888                 if ((sc) && (sc->element)) {
2889                         if (sc->element[_MMCAMCORDER_MAIN_PIPE].gst) {
2890                                 pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
2891                                 if (message->src == (GstObject*)pipeline) {
2892                                         vnewstate = gst_structure_get_value(gst_message_get_structure(message), "new-state");
2893                                         newstate = (GstState)vnewstate->data[0].v_int;
2894                                         _mmcam_dbg_log("GST_MESSAGE_STATE_CHANGED[%s]",gst_element_state_get_name(newstate));
2895                                 }
2896                         }
2897                 }
2898                 break;
2899         }
2900         case GST_MESSAGE_STATE_DIRTY:
2901                 _mmcam_dbg_log("GST_MESSAGE_STATE_DIRTY");
2902                 break;
2903         case GST_MESSAGE_STEP_DONE:
2904                 _mmcam_dbg_log("GST_MESSAGE_STEP_DONE");
2905                 break;
2906         case GST_MESSAGE_CLOCK_PROVIDE:
2907                 _mmcam_dbg_log("GST_MESSAGE_CLOCK_PROVIDE");
2908                 break;
2909         case GST_MESSAGE_CLOCK_LOST:
2910                 _mmcam_dbg_log("GST_MESSAGE_CLOCK_LOST");
2911                 break;
2912         case GST_MESSAGE_NEW_CLOCK:
2913         {
2914                 GstClock *pipe_clock = NULL;
2915                 gst_message_parse_new_clock(message, &pipe_clock);
2916                 /*_mmcam_dbg_log("GST_MESSAGE_NEW_CLOCK : %s", (clock ? GST_OBJECT_NAME (clock) : "NULL"));*/
2917                 break;
2918         }
2919         case GST_MESSAGE_STRUCTURE_CHANGE:
2920                 _mmcam_dbg_log("GST_MESSAGE_STRUCTURE_CHANGE");
2921                 break;
2922         case GST_MESSAGE_STREAM_STATUS:
2923                 /*_mmcam_dbg_log("GST_MESSAGE_STREAM_STATUS");*/
2924                 break;
2925         case GST_MESSAGE_APPLICATION:
2926                 _mmcam_dbg_log("GST_MESSAGE_APPLICATION");
2927                 break;
2928         case GST_MESSAGE_ELEMENT:
2929                 /*_mmcam_dbg_log("GST_MESSAGE_ELEMENT");*/
2930                 break;
2931         case GST_MESSAGE_SEGMENT_START:
2932                 _mmcam_dbg_log("GST_MESSAGE_SEGMENT_START");
2933                 break;
2934         case GST_MESSAGE_SEGMENT_DONE:
2935                 _mmcam_dbg_log("GST_MESSAGE_SEGMENT_DONE");
2936                 break;
2937         case GST_MESSAGE_DURATION_CHANGED:
2938                 _mmcam_dbg_log("GST_MESSAGE_DURATION_CHANGED");
2939                 break;
2940         case GST_MESSAGE_LATENCY:
2941                 _mmcam_dbg_log("GST_MESSAGE_LATENCY");
2942                 break;
2943         case GST_MESSAGE_ASYNC_START:
2944                 _mmcam_dbg_log("GST_MESSAGE_ASYNC_START");
2945                 break;
2946         case GST_MESSAGE_ASYNC_DONE:
2947                 /*_mmcam_dbg_log("GST_MESSAGE_ASYNC_DONE");*/
2948                 break;
2949         case GST_MESSAGE_ANY:
2950                 _mmcam_dbg_log("GST_MESSAGE_ANY");
2951                 break;
2952         case GST_MESSAGE_QOS:
2953 //              _mmcam_dbg_log("GST_MESSAGE_QOS");
2954                 break;
2955         default:
2956                 _mmcam_dbg_log("not handled message type=(%d)", GST_MESSAGE_TYPE(message));
2957                 break;
2958         }
2959
2960         return TRUE;
2961 }
2962
2963
2964 GstBusSyncReply _mmcamcorder_pipeline_bus_sync_callback(GstBus *bus, GstMessage *message, gpointer data)
2965 {
2966         GstElement *element = NULL;
2967         GError *err = NULL;
2968         gchar *debug_info = NULL;
2969
2970         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(data);
2971         _MMCamcorderSubContext *sc = NULL;
2972
2973         mmf_return_val_if_fail(hcamcorder, GST_BUS_PASS);
2974         mmf_return_val_if_fail(message, GST_BUS_PASS);
2975
2976         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
2977         mmf_return_val_if_fail(sc, GST_BUS_PASS);
2978
2979         if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR) {
2980                 /* parse error message */
2981                 gst_message_parse_error(message, &err, &debug_info);
2982
2983                 if (debug_info) {
2984                         _mmcam_dbg_err("GST ERROR : %s", debug_info);
2985                         g_free(debug_info);
2986                         debug_info = NULL;
2987                 }
2988
2989                 if (!err) {
2990                         _mmcam_dbg_warn("failed to parse error message");
2991                         return GST_BUS_PASS;
2992                 }
2993
2994                 /* set videosrc element to compare */
2995                 element = GST_ELEMENT_CAST(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
2996
2997                 /* check domain[RESOURCE] and element[VIDEOSRC] */
2998                 if (err->domain == GST_RESOURCE_ERROR &&
2999                     GST_ELEMENT_CAST(message->src) == element) {
3000                         switch (err->code) {
3001                         case GST_RESOURCE_ERROR_BUSY:
3002                                 _mmcam_dbg_err("Camera device [busy]");
3003                                 hcamcorder->error_code = MM_ERROR_CAMCORDER_DEVICE_BUSY;
3004                                 break;
3005                         case GST_RESOURCE_ERROR_OPEN_WRITE:
3006                                 _mmcam_dbg_err("Camera device [open failed]");
3007                                 hcamcorder->error_code = MM_ERROR_COMMON_INVALID_PERMISSION;
3008                                 //sc->error_code = MM_ERROR_CAMCORDER_DEVICE_OPEN; // SECURITY PART REQUEST PRIVILEGE
3009                                 break;
3010                         case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
3011                                 _mmcam_dbg_err("Camera device [open failed]");
3012                                 hcamcorder->error_code = MM_ERROR_CAMCORDER_DEVICE_OPEN;
3013                                 break;
3014                         case GST_RESOURCE_ERROR_OPEN_READ:
3015                                 _mmcam_dbg_err("Camera device [register trouble]");
3016                                 hcamcorder->error_code = MM_ERROR_CAMCORDER_DEVICE_REG_TROUBLE;
3017                                 break;
3018                         case GST_RESOURCE_ERROR_NOT_FOUND:
3019                                 _mmcam_dbg_err("Camera device [device not found]");
3020                                 hcamcorder->error_code = MM_ERROR_CAMCORDER_DEVICE_NOT_FOUND;
3021                                 break;
3022                         case GST_RESOURCE_ERROR_TOO_LAZY:
3023                                 _mmcam_dbg_err("Camera device [timeout]");
3024                                 hcamcorder->error_code = MM_ERROR_CAMCORDER_DEVICE_TIMEOUT;
3025                                 break;
3026                         case GST_RESOURCE_ERROR_SETTINGS:
3027                                 _mmcam_dbg_err("Camera device [not supported]");
3028                                 hcamcorder->error_code = MM_ERROR_CAMCORDER_NOT_SUPPORTED;
3029                                 break;
3030                         case GST_RESOURCE_ERROR_FAILED:
3031                                 _mmcam_dbg_err("Camera device [working failed].");
3032                                 hcamcorder->error_code = MM_ERROR_CAMCORDER_DEVICE_IO;
3033                                 break;
3034                         default:
3035                                 _mmcam_dbg_err("Camera device [General(%d)]", err->code);
3036                                 hcamcorder->error_code = MM_ERROR_CAMCORDER_DEVICE;
3037                                 break;
3038                         }
3039
3040                         hcamcorder->error_occurs = TRUE;
3041                 }
3042
3043                 g_error_free(err);
3044
3045                 /* store error code and drop this message if cmd is running */
3046                 if (hcamcorder->error_code != MM_ERROR_NONE) {
3047                         _MMCamcorderMsgItem msg;
3048
3049                         /* post error to application */
3050                         hcamcorder->error_occurs = TRUE;
3051                         msg.id = MM_MESSAGE_CAMCORDER_ERROR;
3052                         msg.param.code = hcamcorder->error_code;
3053                         _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
3054
3055                         goto DROP_MESSAGE;
3056                 }
3057         } else if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ELEMENT) {
3058                 _MMCamcorderMsgItem msg;
3059
3060                 if (gst_structure_has_name(gst_message_get_structure(message), "avsysvideosrc-AF") ||
3061                     gst_structure_has_name(gst_message_get_structure(message), "camerasrc-AF")) {
3062                         int focus_state = 0;
3063
3064                         gst_structure_get_int(gst_message_get_structure(message), "focus-state", &focus_state);
3065                         _mmcam_dbg_log("Focus State:%d", focus_state);
3066
3067                         msg.id = MM_MESSAGE_CAMCORDER_FOCUS_CHANGED;
3068                         msg.param.code = focus_state;
3069                         _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
3070
3071                         goto DROP_MESSAGE;
3072                 } else if (gst_structure_has_name(gst_message_get_structure(message), "camerasrc-HDR")) {
3073                         int progress = 0;
3074                         int status = 0;
3075
3076                         if (gst_structure_get_int(gst_message_get_structure(message), "progress", &progress)) {
3077                                 gst_structure_get_int(gst_message_get_structure(message), "status", &status);
3078                                 _mmcam_dbg_log("HDR progress %d percent, status %d", progress, status);
3079
3080                                 msg.id = MM_MESSAGE_CAMCORDER_HDR_PROGRESS;
3081                                 msg.param.code = progress;
3082                                 _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
3083                         }
3084
3085                         goto DROP_MESSAGE;
3086                 } else if (gst_structure_has_name(gst_message_get_structure(message), "camerasrc-FD")) {
3087                         int i = 0;
3088                         const GValue *g_value = gst_structure_get_value(gst_message_get_structure(message), "face-info");;
3089                         GstCameraControlFaceDetectInfo *fd_info = NULL;
3090                         MMCamFaceDetectInfo *cam_fd_info = NULL;
3091
3092                         if (g_value) {
3093                                 fd_info = (GstCameraControlFaceDetectInfo *)g_value_get_pointer(g_value);
3094                         }
3095
3096                         if (fd_info == NULL) {
3097                                 _mmcam_dbg_warn("fd_info is NULL");
3098                                 goto DROP_MESSAGE;
3099                         }
3100
3101                         cam_fd_info = (MMCamFaceDetectInfo *)malloc(sizeof(MMCamFaceDetectInfo));
3102                         if (cam_fd_info == NULL) {
3103                                 _mmcam_dbg_warn("cam_fd_info alloc failed");
3104
3105                                 free(fd_info);
3106                                 fd_info = NULL;
3107
3108                                 goto DROP_MESSAGE;
3109                         }
3110
3111                         /* set total face count */
3112                         cam_fd_info->num_of_faces = fd_info->num_of_faces;
3113
3114                         if (cam_fd_info->num_of_faces > 0) {
3115                                 cam_fd_info->face_info = (MMCamFaceInfo *)malloc(sizeof(MMCamFaceInfo) * cam_fd_info->num_of_faces);
3116                                 if (cam_fd_info->face_info) {
3117                                         /* set information of each face */
3118                                         for (i = 0 ; i < fd_info->num_of_faces ; i++) {
3119                                                 cam_fd_info->face_info[i].id = fd_info->face_info[i].id;
3120                                                 cam_fd_info->face_info[i].score = fd_info->face_info[i].score;
3121                                                 cam_fd_info->face_info[i].rect.x = fd_info->face_info[i].rect.x;
3122                                                 cam_fd_info->face_info[i].rect.y = fd_info->face_info[i].rect.y;
3123                                                 cam_fd_info->face_info[i].rect.width = fd_info->face_info[i].rect.width;
3124                                                 cam_fd_info->face_info[i].rect.height = fd_info->face_info[i].rect.height;
3125                                                 /*
3126                                                 _mmcam_dbg_log("id %d, score %d, [%d,%d,%dx%d]",
3127                                                                fd_info->face_info[i].id,
3128                                                                fd_info->face_info[i].score,
3129                                                                fd_info->face_info[i].rect.x,
3130                                                                fd_info->face_info[i].rect.y,
3131                                                                fd_info->face_info[i].rect.width,
3132                                                                fd_info->face_info[i].rect.height);
3133                                                 */
3134                                         }
3135                                 } else {
3136                                         _mmcam_dbg_warn("MMCamFaceInfo alloc failed");
3137
3138                                         /* free allocated memory that is not sent */
3139                                         free(cam_fd_info);
3140                                         cam_fd_info = NULL;
3141                                 }
3142                         } else {
3143                                 cam_fd_info->face_info = NULL;
3144                         }
3145
3146                         if (cam_fd_info) {
3147                                 /* send message  - cam_fd_info should be freed by application */
3148                                 msg.id = MM_MESSAGE_CAMCORDER_FACE_DETECT_INFO;
3149                                 msg.param.data = cam_fd_info;
3150                                 msg.param.size = sizeof(MMCamFaceDetectInfo);
3151                                 msg.param.code = 0;
3152
3153                                 _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
3154                         }
3155
3156                         /* free fd_info allocated by plugin */
3157                         free(fd_info);
3158                         fd_info = NULL;
3159
3160                         goto DROP_MESSAGE;
3161                 } else if (gst_structure_has_name(gst_message_get_structure(message), "camerasrc-Capture")) {
3162                         int capture_done = FALSE;
3163
3164                         if (gst_structure_get_int(gst_message_get_structure(message), "capture-done", &capture_done)) {
3165                                 sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
3166                                 if (sc && sc->info_image) {
3167                                         /* play capture sound */
3168                                         _mmcamcorder_sound_solo_play((MMHandleType)hcamcorder, _MMCAMCORDER_FILEPATH_CAPTURE_SND, FALSE);
3169                                 }
3170                         }
3171
3172                         goto DROP_MESSAGE;
3173                 }
3174         }
3175
3176         return GST_BUS_PASS;
3177 DROP_MESSAGE:
3178         gst_message_unref(message);
3179         message = NULL;
3180
3181         return GST_BUS_DROP;
3182 }
3183
3184
3185 GstBusSyncReply _mmcamcorder_audio_pipeline_bus_sync_callback(GstBus *bus, GstMessage *message, gpointer data)
3186 {
3187         GstElement *element = NULL;
3188         GError *err = NULL;
3189         gchar *debug_info = NULL;
3190
3191         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(data);
3192         _MMCamcorderSubContext *sc = NULL;
3193
3194         mmf_return_val_if_fail(hcamcorder, GST_BUS_PASS);
3195         mmf_return_val_if_fail(message, GST_BUS_PASS);
3196
3197         sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
3198         mmf_return_val_if_fail(sc, GST_BUS_PASS);
3199
3200         if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR) {
3201                 /* parse error message */
3202                 gst_message_parse_error(message, &err, &debug_info);
3203
3204                 if (debug_info) {
3205                         _mmcam_dbg_err("GST ERROR : %s", debug_info);
3206                         g_free(debug_info);
3207                         debug_info = NULL;
3208                 }
3209
3210                 if (!err) {
3211                         _mmcam_dbg_warn("failed to parse error message");
3212                         return GST_BUS_PASS;
3213                 }
3214
3215                 /* set videosrc element to compare */
3216                 element = GST_ELEMENT_CAST(sc->encode_element[_MMCAMCORDER_AUDIOSRC_SRC].gst);
3217
3218                 /* check domain[RESOURCE] and element[VIDEOSRC] */
3219                 if (err->domain == GST_RESOURCE_ERROR &&
3220                     GST_ELEMENT_CAST(message->src) == element) {
3221                         _MMCamcorderMsgItem msg;
3222                         switch (err->code) {
3223                         case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
3224                         case GST_RESOURCE_ERROR_OPEN_WRITE:
3225                                 _mmcam_dbg_err("audio device [open failed]");
3226                                 hcamcorder->error_code = MM_ERROR_COMMON_INVALID_PERMISSION;
3227                                 /* post error to application */
3228                                 hcamcorder->error_occurs = TRUE;
3229                                 msg.id = MM_MESSAGE_CAMCORDER_ERROR;
3230                                 msg.param.code = hcamcorder->error_code;
3231                                 _mmcam_dbg_err(" error : sc->error_occurs %d", hcamcorder->error_occurs);
3232                                 g_error_free(err);
3233                                 _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
3234                                 gst_message_unref(message);
3235                                 message = NULL;
3236                                 return GST_BUS_DROP;
3237                         default:
3238                                 break;
3239                         }
3240                 }
3241
3242                 g_error_free(err);
3243
3244         }
3245
3246         return GST_BUS_PASS;
3247 }
3248
3249
3250 ASM_cb_result_t _mmcamcorder_asm_callback(int handle, ASM_event_sources_t event_src,
3251                                           ASM_sound_commands_t command,
3252                                           unsigned int sound_status, void* cb_data)
3253 {
3254         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(cb_data);
3255         int current_state = MM_CAMCORDER_STATE_NONE;
3256         ASM_cb_result_t cb_res = ASM_CB_RES_NONE;
3257
3258         mmf_return_val_if_fail((MMHandleType)hcamcorder, ASM_CB_RES_NONE);
3259
3260         current_state = _mmcamcorder_get_state((MMHandleType)hcamcorder);
3261         if (current_state <= MM_CAMCORDER_STATE_NONE ||
3262             current_state >= MM_CAMCORDER_STATE_NUM) {
3263                 _mmcam_dbg_err("Abnormal state. Or null handle. (%p, %d, %d)", hcamcorder, command, current_state);
3264         }
3265
3266         /* set value to inform a status is changed by asm */
3267         hcamcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_BY_ASM;
3268
3269         /* set ASM event code for sending it to application */
3270         hcamcorder->asm_event_code = event_src;
3271
3272         _mmcam_dbg_log("ASM SHARE callback : event code 0x%x, command 0x%x", event_src, command);
3273
3274         _MMCAMCORDER_LOCK_ASM(hcamcorder);
3275
3276         switch (command) {
3277         case ASM_COMMAND_PAUSE:
3278                 _mmcam_dbg_log("Got msg from asm to Pause(state:%d)", current_state);
3279
3280                 __mmcamcorder_force_stop(hcamcorder);
3281                 cb_res = ASM_CB_RES_STOP;
3282
3283                 _mmcam_dbg_log("Finish opeartion.");
3284                 break;
3285         case ASM_COMMAND_STOP:
3286                 _mmcam_dbg_log("Got msg from asm to Stop(state:%d)", current_state);
3287
3288                 __mmcamcorder_force_stop(hcamcorder);
3289                 cb_res = ASM_CB_RES_STOP;
3290
3291                 _mmcam_dbg_log("Finish opeartion. Camera is released.(%d)", cb_res);
3292                 break;
3293         case ASM_COMMAND_PLAY:
3294                 _mmcam_dbg_log("Got msg from asm to Play(state %d)", current_state);
3295
3296                 if (current_state >= MM_CAMCORDER_STATE_PREPARE) {
3297                         _mmcam_dbg_log("Already start previewing");
3298                 } else {
3299                         __mmcamcorder_force_resume(hcamcorder);
3300                 }
3301
3302                 cb_res = ASM_CB_RES_PLAYING;
3303
3304                 _mmcam_dbg_log("Finish opeartion. Preview is started.(%d)", cb_res);
3305                 break;
3306         case ASM_COMMAND_RESUME:
3307         {
3308                 _MMCamcorderMsgItem msg;
3309
3310                 _mmcam_dbg_log("Got msg from asm to Resume(state %d)", current_state);
3311
3312                 msg.id = MM_MESSAGE_READY_TO_RESUME;
3313                 _mmcamcorder_send_message((MMHandleType)hcamcorder, &msg);
3314                 cb_res = ASM_CB_RES_PLAYING;
3315
3316                 _mmcam_dbg_log("Finish opeartion.(%d)", cb_res);
3317                 break;
3318         }
3319         default: /* should not be reached here */
3320                 cb_res = ASM_CB_RES_PLAYING;
3321                 _mmcam_dbg_err("Command[%d] err", command);
3322                 break;
3323         }
3324
3325         /* restore value */
3326         hcamcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_NORMAL;
3327
3328         _MMCAMCORDER_UNLOCK_ASM(hcamcorder);
3329
3330         return cb_res;
3331 }
3332
3333
3334 int _mmcamcorder_create_pipeline(MMHandleType handle, int type)
3335 {
3336         int ret = MM_ERROR_NONE;
3337         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
3338         _MMCamcorderSubContext *sc = NULL;
3339         GstElement *pipeline = NULL;
3340
3341         _mmcam_dbg_log("handle : %x, type : %d", handle, type);
3342
3343         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
3344
3345         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
3346         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
3347
3348         switch (type) {
3349         case MM_CAMCORDER_MODE_AUDIO:
3350                 ret = _mmcamcorder_create_audio_pipeline(handle);
3351                 if (ret != MM_ERROR_NONE) {
3352                         return ret;
3353                 }
3354                 break;
3355         case MM_CAMCORDER_MODE_VIDEO_CAPTURE:
3356         default:
3357                 ret = _mmcamcorder_create_preview_pipeline(handle);
3358                 if (ret != MM_ERROR_NONE) {
3359                         return ret;
3360                 }
3361
3362                 /* connect capture signal */
3363                 if (!sc->bencbin_capture) {
3364                         ret = _mmcamcorder_connect_capture_signal(handle);
3365                         if (ret != MM_ERROR_NONE) {
3366                                 return ret;
3367                         }
3368                 }
3369                 break;
3370         }
3371
3372         pipeline = sc->element[_MMCAMCORDER_MAIN_PIPE].gst;
3373         if (type != MM_CAMCORDER_MODE_AUDIO) {
3374                 traceBegin(TTRACE_TAG_CAMERA, "MMCAMCORDER:REALIZE:SET_READY_TO_PIPELINE");
3375                 ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_READY);
3376                 traceEnd(TTRACE_TAG_CAMERA);
3377         }
3378 #ifdef _MMCAMCORDER_GET_DEVICE_INFO
3379         if (!_mmcamcorder_get_device_info(handle)) {
3380                 _mmcam_dbg_err("Getting device information error!!");
3381         }
3382 #endif
3383
3384         _mmcam_dbg_log("ret[%x]", ret);
3385         if (ret != MM_ERROR_NONE) {
3386                 _mmcam_dbg_err("error : destroy pipeline");
3387                 _mmcamcorder_destroy_pipeline(handle, hcamcorder->type);
3388         }
3389
3390         return ret;
3391 }
3392
3393
3394 void _mmcamcorder_destroy_pipeline(MMHandleType handle, int type)
3395 {
3396         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
3397         _MMCamcorderSubContext *sc = NULL;
3398         gint i = 0;
3399         int element_num = 0;
3400         _MMCamcorderGstElement *element = NULL;
3401         GstBus *bus = NULL;
3402
3403         mmf_return_if_fail(hcamcorder);
3404
3405         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
3406         mmf_return_if_fail(sc);
3407
3408         _mmcam_dbg_log("");
3409
3410         /* Inside each pipeline destroy function, Set GST_STATE_NULL to Main pipeline */
3411         switch (type) {
3412         case MM_CAMCORDER_MODE_VIDEO_CAPTURE:
3413                 element = sc->element;
3414                 element_num = sc->element_num;
3415                 bus = gst_pipeline_get_bus(GST_PIPELINE(sc->element[_MMCAMCORDER_MAIN_PIPE].gst));
3416                 _mmcamcorder_destroy_video_capture_pipeline(handle);
3417                 break;
3418         case MM_CAMCORDER_MODE_AUDIO:
3419                 element = sc->encode_element;
3420                 element_num = sc->encode_element_num;
3421                 bus = gst_pipeline_get_bus(GST_PIPELINE(sc->encode_element[_MMCAMCORDER_ENCODE_MAIN_PIPE].gst));
3422                 _mmcamcorder_destroy_audio_pipeline(handle);
3423                 break;
3424         default:
3425                 _mmcam_dbg_err("unknown type %d", type);
3426                 break;
3427         }
3428
3429         _mmcam_dbg_log("Pipeline clear!!");
3430
3431         /* Remove pipeline message callback */
3432         g_source_remove(hcamcorder->pipeline_cb_event_id);
3433         hcamcorder->pipeline_cb_event_id = 0;
3434
3435         /* Remove remained message in bus */
3436         if (bus) {
3437                 GstMessage *gst_msg = NULL;
3438                 while ((gst_msg = gst_bus_pop(bus)) != NULL) {
3439                         _mmcamcorder_pipeline_cb_message(bus, gst_msg, (gpointer)hcamcorder);
3440                         gst_message_unref( gst_msg );
3441                         gst_msg = NULL;
3442                 }
3443                 gst_object_unref( bus );
3444                 bus = NULL;
3445         }
3446
3447         /* checking unreleased element */
3448         for (i = 0 ; i < element_num ; i++ ) {
3449                 if (element[i].gst) {
3450                         if (GST_IS_ELEMENT(element[i].gst)) {
3451                                 _mmcam_dbg_warn("Still alive element - ID[%d], name [%s], ref count[%d], status[%s]",
3452                                                 element[i].id,
3453                                                 GST_OBJECT_NAME(element[i].gst),
3454                                                 GST_OBJECT_REFCOUNT(element[i].gst),
3455                                                 gst_element_state_get_name(GST_STATE(element[i].gst)));
3456                                 g_object_weak_unref(G_OBJECT(element[i].gst), (GWeakNotify)_mmcamcorder_element_release_noti, sc);
3457                         } else {
3458                                 _mmcam_dbg_warn("The element[%d] is still aliving, check it", element[i].id);
3459                         }
3460
3461                         element[i].id = _MMCAMCORDER_NONE;
3462                         element[i].gst = NULL;
3463                 }
3464         }
3465
3466         return;
3467 }
3468
3469
3470 int _mmcamcorder_gst_set_state_async(MMHandleType handle, GstElement *pipeline, GstState target_state)
3471 {
3472         GstStateChangeReturn setChangeReturn = GST_STATE_CHANGE_FAILURE;
3473
3474         _MMCAMCORDER_LOCK_GST_STATE(handle);
3475         setChangeReturn = gst_element_set_state(pipeline, target_state);
3476         _MMCAMCORDER_UNLOCK_GST_STATE(handle);
3477
3478         return setChangeReturn;
3479 }
3480
3481
3482 #ifdef _MMCAMCORDER_USE_SET_ATTR_CB
3483 static gboolean __mmcamcorder_set_attr_to_camsensor_cb(gpointer data)
3484 {
3485         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(data);
3486
3487         mmf_return_val_if_fail(hcamcorder, FALSE);
3488
3489         _mmcam_dbg_log("");
3490
3491         _mmcamcorder_set_attribute_to_camsensor((MMHandleType)hcamcorder);
3492
3493         /* initialize */
3494         hcamcorder->setting_event_id = 0;
3495
3496         _mmcam_dbg_log("Done");
3497
3498         /* once */
3499         return FALSE;
3500 }
3501 #endif /* _MMCAMCORDER_USE_SET_ATTR_CB */
3502
3503
3504 int _mmcamcorder_gst_set_state(MMHandleType handle, GstElement *pipeline, GstState target_state)
3505 {
3506         unsigned int k = 0;
3507         _MMCamcorderSubContext *sc = NULL;
3508         GstState pipeline_state = GST_STATE_VOID_PENDING;
3509         GstStateChangeReturn setChangeReturn = GST_STATE_CHANGE_FAILURE;
3510         GstStateChangeReturn getChangeReturn = GST_STATE_CHANGE_FAILURE;
3511         GstClockTime get_timeout = __MMCAMCORDER_SET_GST_STATE_TIMEOUT * GST_SECOND;
3512         pthread_mutex_t *state_lock = NULL;
3513
3514         mmf_return_val_if_fail(handle, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
3515         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
3516         mmf_return_val_if_fail(sc && sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
3517
3518         if (sc->element[_MMCAMCORDER_MAIN_PIPE].gst == pipeline) {
3519                 _mmcam_dbg_log("Set state to %d - PREVIEW PIPELINE", target_state);
3520                 state_lock = &_MMCAMCORDER_GET_GST_STATE_LOCK(handle);
3521         } else {
3522                 _mmcam_dbg_log("Set state to %d - ENDODE PIPELINE", target_state);
3523                 state_lock = &_MMCAMCORDER_GET_GST_ENCODE_STATE_LOCK(handle);
3524         }
3525
3526         pthread_mutex_lock(state_lock);
3527
3528         for (k = 0; k < _MMCAMCORDER_STATE_SET_COUNT; k++) {
3529                 setChangeReturn = gst_element_set_state(pipeline, target_state);
3530                 _mmcam_dbg_log("gst_element_set_state[%d] return %d",
3531                                target_state, setChangeReturn);
3532                 if (setChangeReturn != GST_STATE_CHANGE_FAILURE) {
3533                         getChangeReturn = gst_element_get_state(pipeline, &pipeline_state, NULL, get_timeout);
3534                         switch (getChangeReturn) {
3535                         case GST_STATE_CHANGE_NO_PREROLL:
3536                                 _mmcam_dbg_log("status=GST_STATE_CHANGE_NO_PREROLL.");
3537                         case GST_STATE_CHANGE_SUCCESS:
3538                                 /* if we reached the final target state, exit */
3539                                 if (pipeline_state == target_state) {
3540                                         _mmcam_dbg_log("Set state to %d - DONE", target_state);
3541                                         pthread_mutex_unlock(state_lock);
3542                                         return MM_ERROR_NONE;
3543                                 }
3544                                 break;
3545                         case GST_STATE_CHANGE_ASYNC:
3546                                 _mmcam_dbg_log("status=GST_STATE_CHANGE_ASYNC.");
3547                                 break;
3548                         default:
3549                                 pthread_mutex_unlock(state_lock);
3550                                 _mmcam_dbg_log("status=GST_STATE_CHANGE_FAILURE.");
3551                                 return MM_ERROR_CAMCORDER_GST_STATECHANGE;
3552                         }
3553
3554                         pthread_mutex_unlock(state_lock);
3555
3556                         _mmcam_dbg_err("timeout of gst_element_get_state()!!");
3557
3558                         return MM_ERROR_CAMCORDER_RESPONSE_TIMEOUT;
3559                 }
3560                 usleep(_MMCAMCORDER_STATE_CHECK_INTERVAL);
3561         }
3562
3563         pthread_mutex_unlock(state_lock);
3564
3565         _mmcam_dbg_err("Failure. gst_element_set_state timeout!!");
3566
3567         return MM_ERROR_CAMCORDER_RESPONSE_TIMEOUT;
3568 }
3569
3570
3571 /* For performance check */
3572 int _mmcamcorder_video_current_framerate(MMHandleType handle)
3573 {
3574         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
3575         _MMCamcorderSubContext *sc = NULL;
3576
3577         mmf_return_val_if_fail(hcamcorder, -1);
3578
3579         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
3580         mmf_return_val_if_fail(sc, -1);
3581
3582         return sc->kpi.current_fps;
3583 }
3584
3585
3586 int _mmcamcorder_video_average_framerate(MMHandleType handle)
3587 {
3588         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
3589         _MMCamcorderSubContext *sc = NULL;
3590
3591         mmf_return_val_if_fail(hcamcorder, -1);
3592
3593         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
3594         mmf_return_val_if_fail(sc, -1);
3595
3596         return sc->kpi.average_fps;
3597 }
3598
3599
3600 void _mmcamcorder_video_current_framerate_init(MMHandleType handle)
3601 {
3602         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
3603         _MMCamcorderSubContext *sc = NULL;
3604
3605         mmf_return_if_fail(hcamcorder);
3606
3607         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
3608         mmf_return_if_fail(sc);
3609
3610         memset(&(sc->kpi), 0x00, sizeof(_MMCamcorderKPIMeasure));
3611
3612         return;
3613 }
3614
3615
3616 static void __mmcamcorder_force_stop(mmf_camcorder_t *hcamcorder)
3617 {
3618         int i = 0;
3619         int loop = 0;
3620         int itr_cnt = 0;
3621         int result = MM_ERROR_NONE;
3622         int cmd_try_count = 0;
3623         int current_state = MM_CAMCORDER_STATE_NONE;
3624
3625         mmf_return_if_fail(hcamcorder);
3626
3627         /* check command running */
3628         do {
3629                 if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
3630                         if (cmd_try_count++ < __MMCAMCORDER_FORCE_STOP_TRY_COUNT) {
3631                                 _mmcam_dbg_warn("Another command is running. try again after %d ms", __MMCAMCORDER_FORCE_STOP_WAIT_TIME/1000);
3632                                 usleep(__MMCAMCORDER_FORCE_STOP_WAIT_TIME);
3633                         } else {
3634                                 _mmcam_dbg_err("wait timeout");
3635                                 break;
3636                         }
3637                 } else {
3638                         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
3639                         break;
3640                 }
3641         } while (TRUE);
3642
3643         current_state = _mmcamcorder_get_state((MMHandleType)hcamcorder);
3644
3645         _mmcam_dbg_warn("Force STOP MMFW Camcorder");
3646
3647         for (loop = 0 ; current_state > MM_CAMCORDER_STATE_NULL && loop < __MMCAMCORDER_CMD_ITERATE_MAX * 3 ; loop++) {
3648                 itr_cnt = __MMCAMCORDER_CMD_ITERATE_MAX;
3649                 switch (current_state) {
3650                 case MM_CAMCORDER_STATE_CAPTURING:
3651                 {
3652                         _MMCamcorderSubContext *sc = MMF_CAMCORDER_SUBCONTEXT(hcamcorder);
3653                         _MMCamcorderImageInfo *info = NULL;
3654
3655                         mmf_return_if_fail(sc);
3656                         mmf_return_if_fail((info = sc->info_image));
3657
3658                         _mmcam_dbg_warn("Stop capturing.");
3659
3660                         /* if caturing isn't finished, waiting for 2 sec to finish real capture operation. check 'info->capturing'. */
3661                         mm_camcorder_set_attributes((MMHandleType)hcamcorder, NULL,
3662                                                     MMCAM_CAPTURE_BREAK_CONTINUOUS_SHOT, TRUE,
3663                                                     NULL);
3664
3665                         for (i = 0; i < 20 && info->capturing; i++) {
3666                                 usleep(100000);
3667                         }
3668
3669                         if (i == 20) {
3670                                 _mmcam_dbg_err("Timeout. Can't check stop capturing.");
3671                         }
3672
3673                         while ((itr_cnt--) && ((result = _mmcamcorder_capture_stop((MMHandleType)hcamcorder)) != MM_ERROR_NONE)) {
3674                                         _mmcam_dbg_warn("Can't stop capturing.(%x)", result);
3675                         }
3676
3677                         break;
3678                 }
3679                 case MM_CAMCORDER_STATE_RECORDING:
3680                 case MM_CAMCORDER_STATE_PAUSED:
3681                 {
3682                         _mmcam_dbg_warn("Stop recording.");
3683
3684                         while ((itr_cnt--) && ((result = _mmcamcorder_commit((MMHandleType)hcamcorder)) != MM_ERROR_NONE)) {
3685                                 _mmcam_dbg_warn("Can't commit.(%x)", result);
3686                         }
3687                         break;
3688                 }
3689                 case MM_CAMCORDER_STATE_PREPARE:
3690                 {
3691                         _mmcam_dbg_warn("Stop preview.");
3692
3693                         while ((itr_cnt--) && ((result = _mmcamcorder_stop((MMHandleType)hcamcorder)) != MM_ERROR_NONE)) {
3694                                 _mmcam_dbg_warn("Can't stop preview.(%x)", result);
3695                         }
3696                         break;
3697                 }
3698                 case MM_CAMCORDER_STATE_READY:
3699                 {
3700                         _mmcam_dbg_warn("unrealize");
3701
3702                         if ((result = _mmcamcorder_unrealize((MMHandleType)hcamcorder)) != MM_ERROR_NONE) {
3703                                 _mmcam_dbg_warn("Can't unrealize.(%x)", result);
3704                         }
3705                         break;
3706                 }
3707                 default:
3708                         _mmcam_dbg_warn("Already stopped.");
3709                         break;
3710                 }
3711
3712                 current_state = _mmcamcorder_get_state((MMHandleType)hcamcorder);
3713         }
3714
3715         _mmcam_dbg_warn( "Done." );
3716
3717         return;
3718 }
3719
3720
3721 static void __mmcamcorder_force_resume(mmf_camcorder_t *hcamcorder)
3722 {
3723         int loop = 0;
3724         int result = MM_ERROR_NONE;
3725         int itr_cnt = 0;
3726         int current_state = MM_CAMCORDER_STATE_NONE;
3727
3728         mmf_return_if_fail(hcamcorder);
3729
3730         _mmcam_dbg_warn("Force RESUME MMFW Camcorder");
3731
3732         current_state = _mmcamcorder_get_state((MMHandleType)hcamcorder);
3733
3734         for (loop = 0 ; current_state < MM_CAMCORDER_STATE_PREPARE && loop < __MMCAMCORDER_CMD_ITERATE_MAX * 3 ; loop++) {
3735                 itr_cnt = __MMCAMCORDER_CMD_ITERATE_MAX;
3736
3737                 switch (current_state) {
3738                 case MM_CAMCORDER_STATE_NULL:
3739                         _mmcam_dbg_warn("Realize");
3740                         while ((itr_cnt--) && ((result = _mmcamcorder_realize((MMHandleType)hcamcorder)) != MM_ERROR_NONE)) {
3741                                 _mmcam_dbg_warn("Can't realize.(%x)", result);
3742                         }
3743                         break;
3744                 case MM_CAMCORDER_STATE_READY:
3745                         _mmcam_dbg_warn("Start previewing");
3746
3747                         while ((itr_cnt--) && ((result = _mmcamcorder_start((MMHandleType)hcamcorder)) != MM_ERROR_NONE)) {
3748                                 _mmcam_dbg_warn("Can't start previewing.(%x)", result);
3749                         }
3750                         break;
3751                 default:
3752                         _mmcam_dbg_warn("Abnormal state.");
3753                         break;
3754                 }
3755
3756                 current_state = _mmcamcorder_get_state((MMHandleType)hcamcorder);
3757         }
3758
3759         _mmcam_dbg_warn("Done.");
3760
3761         return;
3762 }
3763
3764
3765 static gboolean __mmcamcorder_handle_gst_error(MMHandleType handle, GstMessage *message, GError *error)
3766 {
3767         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
3768         _MMCamcorderMsgItem msg;
3769         gchar *msg_src_element;
3770         _MMCamcorderSubContext *sc = NULL;
3771
3772         return_val_if_fail(hcamcorder, FALSE);
3773         return_val_if_fail(error, FALSE);
3774         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
3775         mmf_return_val_if_fail(sc, FALSE);
3776
3777         _mmcam_dbg_log("");
3778
3779         /* filtering filesink related errors */
3780         if (hcamcorder->state == MM_CAMCORDER_STATE_RECORDING &&
3781             (error->code ==  GST_RESOURCE_ERROR_WRITE || error->code ==  GST_RESOURCE_ERROR_SEEK)) {
3782                 if (sc->ferror_count == 2 && sc->ferror_send == FALSE) {
3783                         sc->ferror_send = TRUE;
3784                         msg.param.code = __mmcamcorder_gst_handle_resource_error(handle, error->code, message);
3785                 } else {
3786                         sc->ferror_count++;
3787                         _mmcam_dbg_warn("Skip error");
3788                         return TRUE;
3789                 }
3790         }
3791
3792         if (error->domain == GST_CORE_ERROR) {
3793                 msg.param.code = __mmcamcorder_gst_handle_core_error(handle, error->code, message);
3794         } else if (error->domain == GST_LIBRARY_ERROR) {
3795                 msg.param.code = __mmcamcorder_gst_handle_library_error(handle, error->code, message);
3796         } else if (error->domain == GST_RESOURCE_ERROR) {
3797                 msg.param.code = __mmcamcorder_gst_handle_resource_error(handle, error->code, message);
3798         } else if (error->domain == GST_STREAM_ERROR) {
3799                 msg.param.code = __mmcamcorder_gst_handle_stream_error(handle, error->code, message);
3800         } else {
3801                 _mmcam_dbg_warn("This error domain is not defined.");
3802
3803                 /* we treat system error as an internal error */
3804                 msg.param.code = MM_ERROR_CAMCORDER_INTERNAL;
3805         }
3806
3807         if (message->src) {
3808                 msg_src_element = GST_ELEMENT_NAME(GST_ELEMENT_CAST(message->src));
3809                 _mmcam_dbg_err("-Msg src : [%s] Domain : [%s]   Error : [%s]  Code : [%d] is tranlated to error code : [0x%x]",
3810                                msg_src_element, g_quark_to_string (error->domain), error->message, error->code, msg.param.code);
3811         } else {
3812                 _mmcam_dbg_err("Domain : [%s]   Error : [%s]  Code : [%d] is tranlated to error code : [0x%x]",
3813                                g_quark_to_string (error->domain), error->message, error->code, msg.param.code);
3814         }
3815
3816 #ifdef _MMCAMCORDER_SKIP_GST_FLOW_ERROR
3817         /* Check whether send this error to application */
3818         if (msg.param.code == MM_ERROR_CAMCORDER_GST_FLOW_ERROR) {
3819                 _mmcam_dbg_log("We got the error. But skip it.");
3820                 return TRUE;
3821         }
3822 #endif /* _MMCAMCORDER_SKIP_GST_FLOW_ERROR */
3823
3824         /* post error to application */
3825         hcamcorder->error_occurs = TRUE;
3826         msg.id = MM_MESSAGE_CAMCORDER_ERROR;
3827         _mmcamcorder_send_message(handle, &msg);
3828
3829         return TRUE;
3830 }
3831
3832
3833 static gint __mmcamcorder_gst_handle_core_error(MMHandleType handle, int code, GstMessage *message)
3834 {
3835         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
3836         _MMCamcorderSubContext *sc = NULL;
3837         GstElement *element = NULL;
3838
3839         _mmcam_dbg_log("");
3840
3841         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
3842
3843         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
3844         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
3845
3846         /* Specific plugin - video encoder plugin */
3847         element = GST_ELEMENT_CAST(sc->encode_element[_MMCAMCORDER_ENCSINK_VENC].gst);
3848
3849         if (GST_ELEMENT_CAST(message->src) == element) {
3850                 if (code == GST_CORE_ERROR_NEGOTIATION) {
3851                         return MM_ERROR_CAMCORDER_GST_NEGOTIATION;
3852                 } else {
3853                         return MM_ERROR_CAMCORDER_ENCODER;
3854                 }
3855         }
3856
3857         /* General */
3858         switch (code)
3859         {
3860                 case GST_CORE_ERROR_STATE_CHANGE:
3861                         return MM_ERROR_CAMCORDER_GST_STATECHANGE;
3862                 case GST_CORE_ERROR_NEGOTIATION:
3863                         return MM_ERROR_CAMCORDER_GST_NEGOTIATION;
3864                 case GST_CORE_ERROR_MISSING_PLUGIN:
3865                 case GST_CORE_ERROR_SEEK:
3866                 case GST_CORE_ERROR_NOT_IMPLEMENTED:
3867                 case GST_CORE_ERROR_FAILED:
3868                 case GST_CORE_ERROR_TOO_LAZY:
3869                 case GST_CORE_ERROR_PAD:
3870                 case GST_CORE_ERROR_THREAD:
3871                 case GST_CORE_ERROR_EVENT:
3872                 case GST_CORE_ERROR_CAPS:
3873                 case GST_CORE_ERROR_TAG:
3874                 case GST_CORE_ERROR_CLOCK:
3875                 case GST_CORE_ERROR_DISABLED:
3876                 default:
3877                         return MM_ERROR_CAMCORDER_GST_CORE;
3878                 break;
3879         }
3880 }
3881
3882 static gint __mmcamcorder_gst_handle_library_error(MMHandleType handle, int code, GstMessage *message)
3883 {
3884         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
3885         return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
3886
3887         _mmcam_dbg_log("");
3888
3889         /* Specific plugin - NONE */
3890
3891         /* General */
3892         switch (code) {
3893         case GST_LIBRARY_ERROR_FAILED:
3894         case GST_LIBRARY_ERROR_TOO_LAZY:
3895         case GST_LIBRARY_ERROR_INIT:
3896         case GST_LIBRARY_ERROR_SHUTDOWN:
3897         case GST_LIBRARY_ERROR_SETTINGS:
3898         case GST_LIBRARY_ERROR_ENCODE:
3899         default:
3900                 _mmcam_dbg_err("Library error(%d)", code);
3901                 return MM_ERROR_CAMCORDER_GST_LIBRARY;
3902         }
3903 }
3904
3905
3906 static gint __mmcamcorder_gst_handle_resource_error(MMHandleType handle, int code, GstMessage *message)
3907 {
3908         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
3909         _MMCamcorderSubContext *sc = NULL;
3910         GstElement *element = NULL;
3911
3912         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
3913
3914         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
3915         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
3916
3917         _mmcam_dbg_log("");
3918
3919         /* Specific plugin */
3920         /* video sink */
3921         element = GST_ELEMENT_CAST(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst);
3922         if (GST_ELEMENT_CAST(message->src) == element) {
3923                 if (code == GST_RESOURCE_ERROR_WRITE) {
3924                         _mmcam_dbg_err("Display device [Off]");
3925                         return MM_ERROR_CAMCORDER_DISPLAY_DEVICE_OFF;
3926                 } else {
3927                         _mmcam_dbg_err("Display device [General(%d)]", code);
3928                 }
3929         }
3930
3931         /* encodebin */
3932         element = GST_ELEMENT_CAST(sc->encode_element[_MMCAMCORDER_ENCSINK_VENC].gst);
3933         if (GST_ELEMENT_CAST(message->src) == element) {
3934                 if (code == GST_RESOURCE_ERROR_FAILED) {
3935                         _mmcam_dbg_err("Encoder [Resource error]");
3936                         return MM_ERROR_CAMCORDER_ENCODER_BUFFER;
3937                 } else {
3938                         _mmcam_dbg_err("Encoder [General(%d)]", code);
3939                         return MM_ERROR_CAMCORDER_ENCODER;
3940                 }
3941         }
3942
3943         /* General */
3944         switch (code) {
3945         case GST_RESOURCE_ERROR_WRITE:
3946                 _mmcam_dbg_err("File write error");
3947                 return MM_ERROR_FILE_WRITE;
3948         case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
3949                 _mmcam_dbg_err("No left space");
3950                 return MM_MESSAGE_CAMCORDER_NO_FREE_SPACE;
3951         case GST_RESOURCE_ERROR_OPEN_WRITE:
3952                 _mmcam_dbg_err("Out of storage");
3953                 return MM_ERROR_OUT_OF_STORAGE;
3954         case GST_RESOURCE_ERROR_SEEK:
3955                 _mmcam_dbg_err("File read(seek)");
3956                 return MM_ERROR_FILE_READ;
3957         case GST_RESOURCE_ERROR_NOT_FOUND:
3958         case GST_RESOURCE_ERROR_FAILED:
3959         case GST_RESOURCE_ERROR_TOO_LAZY:
3960         case GST_RESOURCE_ERROR_BUSY:
3961         case GST_RESOURCE_ERROR_OPEN_READ:
3962         case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
3963         case GST_RESOURCE_ERROR_CLOSE:
3964         case GST_RESOURCE_ERROR_READ:
3965         case GST_RESOURCE_ERROR_SYNC:
3966         case GST_RESOURCE_ERROR_SETTINGS:
3967         default:
3968                 _mmcam_dbg_err("Resource error(%d)", code);
3969                 return MM_ERROR_CAMCORDER_GST_RESOURCE;
3970         }
3971 }
3972
3973
3974 static gint __mmcamcorder_gst_handle_stream_error(MMHandleType handle, int code, GstMessage *message)
3975 {
3976         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
3977         _MMCamcorderSubContext *sc = NULL;
3978         GstElement *element =NULL;
3979
3980         mmf_return_val_if_fail( hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED );
3981
3982         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
3983         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
3984
3985         _mmcam_dbg_log("");
3986
3987         /* Specific plugin */
3988         /* video encoder */
3989         element = GST_ELEMENT_CAST(sc->encode_element[_MMCAMCORDER_ENCSINK_VENC].gst);
3990         if (GST_ELEMENT_CAST(message->src) == element) {
3991                 switch (code) {
3992                 case GST_STREAM_ERROR_WRONG_TYPE:
3993                         _mmcam_dbg_err("Video encoder [wrong stream type]");
3994                         return MM_ERROR_CAMCORDER_ENCODER_WRONG_TYPE;
3995                 case GST_STREAM_ERROR_ENCODE:
3996                         _mmcam_dbg_err("Video encoder [encode error]");
3997                         return MM_ERROR_CAMCORDER_ENCODER_WORKING;
3998                 case GST_STREAM_ERROR_FAILED:
3999                         _mmcam_dbg_err("Video encoder [stream failed]");
4000                         return MM_ERROR_CAMCORDER_ENCODER_WORKING;
4001                 default:
4002                         _mmcam_dbg_err("Video encoder [General(%d)]", code);
4003                         return MM_ERROR_CAMCORDER_ENCODER;
4004                 }
4005         }
4006
4007         /* General plugin */
4008         switch (code) {
4009         case GST_STREAM_ERROR_FORMAT:
4010                 _mmcam_dbg_err("General [negotiation error(%d)]", code);
4011                 return MM_ERROR_CAMCORDER_GST_NEGOTIATION;
4012         case GST_STREAM_ERROR_FAILED:
4013                 _mmcam_dbg_err("General [flow error(%d)]", code);
4014                 return MM_ERROR_CAMCORDER_GST_FLOW_ERROR;
4015         case GST_STREAM_ERROR_TYPE_NOT_FOUND:
4016         case GST_STREAM_ERROR_DECODE:
4017         case GST_STREAM_ERROR_CODEC_NOT_FOUND:
4018         case GST_STREAM_ERROR_NOT_IMPLEMENTED:
4019         case GST_STREAM_ERROR_TOO_LAZY:
4020         case GST_STREAM_ERROR_ENCODE:
4021         case GST_STREAM_ERROR_DEMUX:
4022         case GST_STREAM_ERROR_MUX:
4023         case GST_STREAM_ERROR_DECRYPT:
4024         case GST_STREAM_ERROR_DECRYPT_NOKEY:
4025         case GST_STREAM_ERROR_WRONG_TYPE:
4026         default:
4027                 _mmcam_dbg_err("General [error(%d)]", code);
4028                 return MM_ERROR_CAMCORDER_GST_STREAM;
4029         }
4030 }
4031
4032
4033 static gboolean __mmcamcorder_handle_gst_warning (MMHandleType handle, GstMessage *message, GError *error)
4034 {
4035         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
4036         gchar *debug = NULL;
4037         GError *err = NULL;
4038
4039         return_val_if_fail(hcamcorder, FALSE);
4040         return_val_if_fail(error, FALSE);
4041
4042         _mmcam_dbg_log("");
4043
4044         gst_message_parse_warning(message, &err, &debug);
4045
4046         if (error->domain == GST_CORE_ERROR) {
4047                 _mmcam_dbg_warn("GST warning: GST_CORE domain");
4048         } else if (error->domain == GST_LIBRARY_ERROR) {
4049                 _mmcam_dbg_warn("GST warning: GST_LIBRARY domain");
4050         } else if (error->domain == GST_RESOURCE_ERROR) {
4051                 _mmcam_dbg_warn("GST warning: GST_RESOURCE domain");
4052                 __mmcamcorder_gst_handle_resource_warning(handle, message, error);
4053         } else if (error->domain == GST_STREAM_ERROR ) {
4054                 _mmcam_dbg_warn("GST warning: GST_STREAM domain");
4055         } else {
4056                 _mmcam_dbg_warn("This error domain(%d) is not defined.", error->domain);
4057         }
4058
4059         if (err != NULL) {
4060                 g_error_free(err);
4061                 err = NULL;
4062         }
4063         if (debug != NULL) {
4064                 _mmcam_dbg_err ("Debug: %s", debug);
4065                 g_free(debug);
4066                 debug = NULL;
4067         }
4068
4069         return TRUE;
4070 }
4071
4072
4073 static gint __mmcamcorder_gst_handle_resource_warning(MMHandleType handle, GstMessage *message , GError *error)
4074 {
4075         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
4076         _MMCamcorderSubContext *sc = NULL;
4077         GstElement *element =NULL;
4078         gchar *msg_src_element;
4079
4080         mmf_return_val_if_fail( hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED );
4081
4082         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
4083         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
4084
4085         _mmcam_dbg_log("");
4086
4087         /* Special message handling */
4088         /* video source */
4089         element = GST_ELEMENT_CAST(sc->element[_MMCAMCORDER_VIDEOSRC_SRC].gst);
4090         if (GST_ELEMENT_CAST(message->src) == element) {
4091                 if (error->code == GST_RESOURCE_ERROR_FAILED) {
4092                         msg_src_element = GST_ELEMENT_NAME(GST_ELEMENT_CAST(message->src));
4093                         _mmcam_dbg_warn("-Msg src:[%s] Domain:[%s] Error:[%s]",
4094                                        msg_src_element, g_quark_to_string(error->domain), error->message);
4095                         return MM_ERROR_NONE;
4096                 }
4097         }
4098
4099         /* General plugin */
4100         switch (error->code) {
4101         case GST_RESOURCE_ERROR_WRITE:
4102         case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
4103         case GST_RESOURCE_ERROR_SEEK:
4104         case GST_RESOURCE_ERROR_NOT_FOUND:
4105         case GST_RESOURCE_ERROR_FAILED:
4106         case GST_RESOURCE_ERROR_TOO_LAZY:
4107         case GST_RESOURCE_ERROR_BUSY:
4108         case GST_RESOURCE_ERROR_OPEN_READ:
4109         case GST_RESOURCE_ERROR_OPEN_WRITE:
4110         case GST_RESOURCE_ERROR_OPEN_READ_WRITE:
4111         case GST_RESOURCE_ERROR_CLOSE:
4112         case GST_RESOURCE_ERROR_READ:
4113         case GST_RESOURCE_ERROR_SYNC:
4114         case GST_RESOURCE_ERROR_SETTINGS:
4115         default:
4116                 _mmcam_dbg_warn("General GST warning(%d)", error->code);
4117                 break;
4118         }
4119
4120         return MM_ERROR_NONE;
4121 }