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