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