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