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