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