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