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