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