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