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