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