Remove unused header include code
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_mused.c
1 /*
2  * libmm-camcorder
3  *
4  * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Sejong Park <sejong123.park@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 |                                                                                                                                                                                       |
24 |  INCLUDE FILES                                                                                                                                                        |
25 |                                                                                                                                                                                       |
26 ========================================================================================== */
27 #include <glib.h>
28 #include <gst/gst.h>
29 #include <gst/app/gstappsrc.h>
30 #include <gst/video/videooverlay.h>
31 #ifdef HAVE_WAYLAND
32 #include <gst/wayland/wayland.h>
33 #endif
34 #include <unistd.h>
35 #include <sys/stat.h>
36 #include <string.h>
37 #include <sys/time.h>
38 #include <stdlib.h>
39
40 #include <mm_error.h>
41 #include <mm_debug.h>
42
43 #include "mm_camcorder_mused.h"
44 #include "mm_camcorder_internal.h"
45 #include <sched.h>
46
47 #define MMCAMCORDER_MAX_INT     (2147483647)
48
49 #define MMCAMCORDER_FREEIF(x) \
50 if ( x ) \
51         g_free( x ); \
52 x = NULL;
53
54 typedef enum
55 {
56         MM_CAM_MUSED_DISPLAY_SHM_SOCKET_PATH,
57         MM_CAM_MUSED_DISPLAY_HANDLE,
58         MM_CAM_MUSED_DISPLAY_SURFACE,
59         MM_CAM_MUSED_CLIENT_ATTRIBUTE_NUM
60 }MMCamcorderMusedAttrsID;
61
62 MMHandleType
63 _mmcamcorder_mused_alloc_attribute(MMHandleType handle)
64 {
65         _mmcam_dbg_log( "" );
66
67         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
68         MMHandleType attrs = 0;
69         mmf_attrs_construct_info_t *attrs_const_info = NULL;
70         unsigned int attr_count = 0;
71         unsigned int idx;
72
73         if (hcamcorder == NULL) {
74                 _mmcam_dbg_err("handle is NULL");
75                 return 0;
76         }
77
78         /* Create attribute constructor */
79         _mmcam_dbg_log("start");
80
81         /* alloc 'mmf_attrs_construct_info_t' */
82         attr_count = MM_CAM_MUSED_CLIENT_ATTRIBUTE_NUM;
83         attrs_const_info = malloc(attr_count * sizeof(mmf_attrs_construct_info_t));
84         if (!attrs_const_info) {
85                 _mmcam_dbg_err("Fail to alloc constructor.");
86                 return 0;
87         }
88
89         /* alloc default attribute info */
90         hcamcorder->cam_attrs_const_info = (mm_cam_attr_construct_info *)malloc(sizeof(mm_cam_attr_construct_info) * attr_count);
91         if (hcamcorder->cam_attrs_const_info == NULL) {
92                 _mmcam_dbg_err("failed to alloc default attribute info");
93                 free(attrs_const_info);
94                 attrs_const_info = NULL;
95                 return 0;
96         }
97
98         /* basic attributes' info */
99         mm_cam_attr_construct_info temp_info[] = {
100                 {
101                         MM_CAM_MUSED_DISPLAY_SHM_SOCKET_PATH,
102                         "mused-display-shm-socket-path",
103                         MMF_VALUE_TYPE_STRING,
104                         MM_ATTRS_FLAG_RW,
105                         {(void*)NULL},
106                         MM_ATTRS_VALID_TYPE_NONE,
107                         {0},
108                         {0},
109                         NULL,
110                 },
111                 {
112                         MM_CAM_MUSED_DISPLAY_HANDLE,
113                         "mused-display-handle",
114                         MMF_VALUE_TYPE_DATA,
115                         MM_ATTRS_FLAG_RW,
116                         {(void*)NULL},
117                         MM_ATTRS_VALID_TYPE_NONE,
118                         {0},
119                         {0},
120                         NULL,
121                 },
122                 {
123                         MM_CAM_MUSED_DISPLAY_SURFACE,
124                         "mused-display-surface",
125                         MMF_VALUE_TYPE_INT,
126                         MM_ATTRS_FLAG_RW,
127                         {(void*)MM_DISPLAY_SURFACE_X},
128                         MM_ATTRS_VALID_TYPE_INT_RANGE,
129                         MM_DISPLAY_SURFACE_X,
130                         MM_DISPLAY_SURFACE_X_EXT,
131                         NULL,
132                 },
133         };
134
135         memcpy(hcamcorder->cam_attrs_const_info, temp_info, sizeof(mm_cam_attr_construct_info) * attr_count);
136
137         for (idx = 0 ; idx < attr_count ; idx++) {
138                 /* attribute order check. This should be same. */
139                 if (idx != hcamcorder->cam_attrs_const_info[idx].attrid) {
140                         _mmcam_dbg_err("Please check attributes order. Is the idx same with enum val?");
141                         free(attrs_const_info);
142                         attrs_const_info = NULL;
143                         free(hcamcorder->cam_attrs_const_info);
144                         hcamcorder->cam_attrs_const_info = NULL;
145                         return 0;
146                 }
147
148                 attrs_const_info[idx].name = hcamcorder->cam_attrs_const_info[idx].name;
149                 attrs_const_info[idx].value_type = hcamcorder->cam_attrs_const_info[idx].value_type;
150                 attrs_const_info[idx].flags = hcamcorder->cam_attrs_const_info[idx].flags;
151                 attrs_const_info[idx].default_value = hcamcorder->cam_attrs_const_info[idx].default_value.value_void;
152         }
153
154         /* Camcorder Attributes */
155         _mmcam_dbg_log("Create Camcorder Attributes[%p, %d]", attrs_const_info, attr_count);
156
157         attrs = mmf_attrs_new_from_data("Camcorder_Mused_Attributes",
158                                         attrs_const_info,
159                                         attr_count,
160                                         _mmcamcorder_commit_camcorder_attrs,
161                                         (void *)handle);
162
163         free(attrs_const_info);
164         attrs_const_info = NULL;
165
166         if (attrs == 0) {
167                 _mmcam_dbg_err("Fail to alloc attribute handle");
168                 free(hcamcorder->cam_attrs_const_info);
169                 hcamcorder->cam_attrs_const_info = NULL;
170                 return 0;
171         }
172
173         for (idx = 0; idx < attr_count; idx++)
174         {
175                 _mmcam_dbg_log("Valid type [%s]", hcamcorder->cam_attrs_const_info[idx].name);
176
177                 mmf_attrs_set_valid_type (attrs, idx, hcamcorder->cam_attrs_const_info[idx].validity_type);
178
179                 switch (hcamcorder->cam_attrs_const_info[idx].validity_type)
180                 {
181                         case MM_ATTRS_VALID_TYPE_INT_ARRAY:
182                                 if (hcamcorder->cam_attrs_const_info[idx].validity_value_1.int_array &&
183                                     hcamcorder->cam_attrs_const_info[idx].validity_value_2.count > 0) {
184                                         mmf_attrs_set_valid_array(attrs, idx,
185                                                                   (const int *)(hcamcorder->cam_attrs_const_info[idx].validity_value_1.int_array),
186                                                                   hcamcorder->cam_attrs_const_info[idx].validity_value_2.count,
187                                                                   hcamcorder->cam_attrs_const_info[idx].default_value.value_int);
188                                 }
189                         break;
190                         case MM_ATTRS_VALID_TYPE_INT_RANGE:
191                                 _mmcam_dbg_err("MM_ATTRS_VALID_TYPE_INT_RANGE");
192                                 mmf_attrs_set_valid_range(attrs, idx,
193                                                           hcamcorder->cam_attrs_const_info[idx].validity_value_1.int_min,
194                                                           hcamcorder->cam_attrs_const_info[idx].validity_value_2.int_max,
195                                                           hcamcorder->cam_attrs_const_info[idx].default_value.value_int);
196                         break;
197                         case MM_ATTRS_VALID_TYPE_DOUBLE_ARRAY:
198                                 if (hcamcorder->cam_attrs_const_info[idx].validity_value_1.double_array &&
199                                     hcamcorder->cam_attrs_const_info[idx].validity_value_2.count > 0) {
200                                         mmf_attrs_set_valid_double_array(attrs, idx,
201                                                                          (const double *)(hcamcorder->cam_attrs_const_info[idx].validity_value_1.double_array),
202                                                                          hcamcorder->cam_attrs_const_info[idx].validity_value_2.count,
203                                                                          hcamcorder->cam_attrs_const_info[idx].default_value.value_double);
204                                 }
205                         break;
206                         case MM_ATTRS_VALID_TYPE_DOUBLE_RANGE:
207                                 mmf_attrs_set_valid_double_range(attrs, idx,
208                                                                  hcamcorder->cam_attrs_const_info[idx].validity_value_1.double_min,
209                                                                  hcamcorder->cam_attrs_const_info[idx].validity_value_2.double_max,
210                                                                  hcamcorder->cam_attrs_const_info[idx].default_value.value_double);
211                         break;
212                         case MM_ATTRS_VALID_TYPE_NONE:
213                         break;
214                         case MM_ATTRS_VALID_TYPE_INVALID:
215                         default:
216                                 _mmcam_dbg_err("Valid type error.");
217                         break;
218                 }
219         }
220
221         return attrs;
222 }
223
224 int mm_camcorder_mused_create(MMHandleType *handle)
225 {
226         int ret = MM_ERROR_NONE;
227         int UseConfCtrl = 0;
228         int rcmd_fmt_capture = MM_PIXEL_FORMAT_YUYV;
229         int rcmd_fmt_recording = MM_PIXEL_FORMAT_NV12;
230         int rcmd_dpy_rotation = MM_DISPLAY_ROTATION_270;
231         int play_capture_sound = TRUE;
232         int camera_device_count = MM_VIDEO_DEVICE_NUM;
233         int camera_facing_direction = MM_CAMCORDER_CAMERA_FACING_DIRECTION_REAR;
234         int resource_fd = -1;
235         char *err_attr_name = NULL;
236         const char *ConfCtrlFile = NULL;
237         mmf_camcorder_t *hcamcorder = NULL;
238         type_element *EvasSurfaceElement = NULL;
239
240         _mmcam_dbg_log("Enter");
241
242         mmf_return_val_if_fail(handle, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
243
244         /* Create mmf_camcorder_t handle and initialize every variable */
245         hcamcorder = (mmf_camcorder_t *)malloc(sizeof(mmf_camcorder_t));
246         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_LOW_MEMORY);
247         memset(hcamcorder, 0x00, sizeof(mmf_camcorder_t));
248
249         /* init values */
250         hcamcorder->type = 0;
251         hcamcorder->state = MM_CAMCORDER_STATE_NONE;
252         hcamcorder->sub_context = NULL;
253         hcamcorder->target_state = MM_CAMCORDER_STATE_NULL;
254         hcamcorder->capture_in_recording = FALSE;
255
256         pthread_mutex_init(&((hcamcorder->mtsafe).lock), NULL);
257         pthread_cond_init(&((hcamcorder->mtsafe).cond), NULL);
258         pthread_mutex_init(&((hcamcorder->mtsafe).cmd_lock), NULL);
259         pthread_mutex_init(&((hcamcorder->mtsafe).state_lock), NULL);
260         pthread_mutex_init(&((hcamcorder->mtsafe).gst_state_lock), NULL);
261         pthread_mutex_init(&((hcamcorder->mtsafe).message_cb_lock), NULL);
262         pthread_mutex_init(&(hcamcorder->restart_preview_lock), NULL);
263
264         /* Get Camera Configure information from Camcorder INI file */
265         _mmcamcorder_conf_get_info((MMHandleType)hcamcorder, CONFIGURE_TYPE_MAIN, CONFIGURE_MAIN_FILE, &hcamcorder->conf_main);
266
267         if (!(hcamcorder->conf_main)) {
268                 _mmcam_dbg_err( "Failed to get configure(main) info." );
269
270                 ret = MM_ERROR_CAMCORDER_CREATE_CONFIGURE;
271                 goto _ERR_AFTER_ASM_REGISTER;
272         }
273         _mmcam_dbg_log("aloc attribute handle : 0x%x", (MMHandleType)hcamcorder);
274         hcamcorder->attributes = _mmcamcorder_mused_alloc_attribute((MMHandleType)hcamcorder);
275         if (!(hcamcorder->attributes)) {
276                 _mmcam_dbg_err("_mmcamcorder_create::alloc attribute error.");
277
278                 ret = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
279                 goto _ERR_AFTER_ASM_REGISTER;
280         }
281
282         /* Set initial state */
283         _mmcamcorder_set_state((MMHandleType)hcamcorder, MM_CAMCORDER_STATE_NULL);
284
285         _mmcam_dbg_log("created handle %p", hcamcorder);
286
287         *handle = (MMHandleType)hcamcorder;
288         _mmcam_dbg_log("created client handle : 0x%x", *handle);
289
290         return MM_ERROR_NONE;
291
292 _ERR_AFTER_ASM_REGISTER:
293
294 _ERR_DEFAULT_VALUE_INIT:
295         /* Release lock, cond */
296         pthread_mutex_destroy(&((hcamcorder->mtsafe).lock));
297         pthread_cond_destroy(&((hcamcorder->mtsafe).cond));
298         pthread_mutex_destroy(&((hcamcorder->mtsafe).cmd_lock));
299         pthread_mutex_destroy(&((hcamcorder->mtsafe).state_lock));
300         pthread_mutex_destroy(&((hcamcorder->mtsafe).gst_state_lock));
301         pthread_mutex_destroy(&((hcamcorder->mtsafe).gst_encode_state_lock));
302         pthread_mutex_destroy(&((hcamcorder->mtsafe).message_cb_lock));
303
304         pthread_mutex_destroy(&(hcamcorder->restart_preview_lock));
305
306         if (hcamcorder->conf_ctrl) {
307                 _mmcamcorder_conf_release_info(handle, &hcamcorder->conf_ctrl);
308         }
309
310         if (hcamcorder->conf_main) {
311                 _mmcamcorder_conf_release_info(handle, &hcamcorder->conf_main);
312         }
313
314         /* Release handle */
315         memset(hcamcorder, 0x00, sizeof(mmf_camcorder_t));
316         free(hcamcorder);
317
318         return ret;
319 }
320
321 int _mmcamcorder_mused_videosink_window_set(MMHandleType handle)
322 {
323         int err = MM_ERROR_NONE;
324         int *overlay = NULL;
325         char *err_name = NULL;
326         const char *videosink_name = NULL;
327         int size = 0;
328
329         GstElement *vsink = NULL;
330         MMCamWaylandInfo *wl_info = NULL;
331
332         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
333         _MMCamcorderSubContext *sc = NULL;
334
335         _mmcam_dbg_log("Enter");
336
337         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
338
339         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
340         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
341         mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
342         mmf_return_val_if_fail(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
343
344         vsink = sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst;
345
346         /* Get video display information */
347         err = mm_camcorder_get_attributes(handle, &err_name,
348                                           MMCAM_MUSED_DISPLAY_HANDLE, (void**)&overlay, &size,
349                                           NULL);
350         if (err != MM_ERROR_NONE) {
351                 if (err_name) {
352                         _mmcam_dbg_err("failed to get attributes [%s][0x%x]", err_name, err);
353                         free(err_name);
354                         err_name = NULL;
355                 } else {
356                         _mmcam_dbg_err("failed to get attributes [0x%x]", err);
357                 }
358
359                 return err;
360         }
361         wl_info = (MMCamWaylandInfo *)overlay;
362         if (wl_info) {
363                 GstContext *context = NULL;
364
365                 context = gst_wayland_display_handle_context_new((struct wl_display *)wl_info->display);
366                 if (context) {
367                         gst_element_set_context(vsink, context);
368                 } else {
369                         _mmcam_dbg_warn("gst_wayland_display_handle_context_new failed");
370                 }
371
372                 gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(vsink), (guintptr)wl_info->surface);
373                 gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(vsink),
374                                                        wl_info->window_x,
375                                                        wl_info->window_y,
376                                                        wl_info->window_width,
377                                                        wl_info->window_height);
378
379         } else {
380                 _mmcam_dbg_err("Display Handle is invalid");
381         }
382
383         return MM_ERROR_NONE;
384 }
385
386 void __mmcamcorder_mused_gst_destroy_pipeline(MMHandleType handle)
387 {
388         _MMCamcorderSubContext *sc;
389         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
390
391         _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_CLIENT_VIDEOSRC_SRC);
392         _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_CLIENT_VIDEOSINK_SINK);
393         _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_CLIENT_MAIN_PIPE);
394         return;
395 }
396
397 void mm_camcorder_mused_destroy(MMHandleType handle)
398 {
399         int result = MM_ERROR_NONE;
400         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
401
402         _MMCAMCORDER_TRYLOCK_CMD(hcamcorder);
403
404         __mmcamcorder_mused_gst_destroy_pipeline(handle);
405         _mmcamcorder_dealloc_attribute(handle, hcamcorder->attributes);
406         g_free(handle);
407
408         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
409
410         return;
411 }
412
413
414 int mm_camcorder_mused_realize(MMHandleType handle, char *caps)
415 {
416         int result = MM_ERROR_NONE;
417
418         result = _mmcamcorder_mused_realize(handle, caps);
419
420         return result;
421 }
422
423 int _mmcamcorder_mused_realize(MMHandleType handle, char *string_caps)
424 {
425         int ret = MM_ERROR_NONE;
426         GstElement *src;
427         GstElement *sink;
428         GstBus *bus;
429         GstCaps *caps;
430         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
431         MMHandleType attrs = hcamcorder->attributes;
432         int width = 0;
433         int height = 0;
434         gboolean link;
435         char *socket_path = NULL;
436         int socket_path_length;
437         int attr_ret;
438         int surface_type = 0;
439         gchar *videosink_element = NULL;
440         gchar *videosrc_element = NULL;
441
442         int state = MM_CAMCORDER_STATE_NONE;
443         int state_FROM = MM_CAMCORDER_STATE_NULL;
444         int state_TO = MM_CAMCORDER_STATE_READY;
445         int vconf_camera_state = 0;
446         _MMCamcorderSubContext *sc;
447         GList *element_list = NULL;
448         GstElement *pipeline = NULL;
449
450
451         _mmcam_dbg_err("Enter");
452
453         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
454                 _mmcam_dbg_err("Another command is running.");
455                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
456                 goto _ERR_CAMCORDER_CMD_PRECON;
457         }
458
459         state = _mmcamcorder_get_state(handle);
460         if (state != state_FROM) {
461                 _mmcam_dbg_err("Wrong state(%d)", state);
462                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
463                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
464         }
465
466         /* alloc sub context */
467         hcamcorder->sub_context = _mmcamcorder_alloc_subcontext(hcamcorder->type);
468         if(!hcamcorder->sub_context) {
469                 ret = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
470                 goto _ERR_CAMCORDER_CMD;
471         }
472
473         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
474
475         /* create pipeline */
476         _MMCAMCORDER_PIPELINE_MAKE(sc, sc->element, _MMCAMCORDER_CLIENT_MAIN_PIPE, "camera_client", ret);
477
478         /* create source */
479         _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_CLIENT_VIDEOSRC_SRC, "shmsrc", "shmsrc", element_list, ret);
480
481         mm_camcorder_get_attributes(handle, NULL,
482                                     MMCAM_MUSED_DISPLAY_SHM_SOCKET_PATH, &socket_path, &socket_path_length,
483                                     NULL);
484
485         g_object_set(sc->element[_MMCAMCORDER_CLIENT_VIDEOSRC_SRC].gst,
486                         "socket-path", socket_path,
487                         "is-live", TRUE,
488                         NULL);
489
490         /* create sink */
491         _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_CLIENT_VIDEOSINK_SINK, "waylandsink", "waylandsink", element_list, ret);
492
493         g_object_set(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst,
494                         "draw-borders", 0,
495                         "force-aspect-ratio", 1,
496                         "enable-last-sample",0,
497                         "qos",0,
498                         "sync",0,
499                         "show-preroll-frame",0,
500                         NULL);
501
502         if (_mmcamcorder_mused_videosink_window_set(handle) != MM_ERROR_NONE) {
503                 _mmcam_dbg_err("_mmcamcorder_videosink_window_set error");
504                 ret = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
505                 goto pipeline_creation_error;
506         }
507
508         /* add elements to main pipeline */
509         if (!_mmcamcorder_add_elements_to_bin(GST_BIN(sc->element[_MMCAMCORDER_CLIENT_MAIN_PIPE].gst), element_list)) {
510                 _mmcam_dbg_err("element_list add error.");
511                 ret = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
512                 goto pipeline_creation_error;
513         }
514
515         caps = gst_caps_from_string(string_caps);
516         /* link elements */
517         if (!_mmcamcorder_filtered_link_elements(element_list, caps)) {
518                 _mmcam_dbg_err( "element link error." );
519                 ret = MM_ERROR_CAMCORDER_GST_LINK;
520                 goto pipeline_creation_error;
521         }
522
523         pipeline = sc->element[_MMCAMCORDER_CLIENT_MAIN_PIPE].gst;
524
525         ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_READY);
526         if (ret != MM_ERROR_NONE) {
527                 _mmcam_dbg_err("error : destroy pipeline");
528                 _mmcamcorder_destroy_pipeline(handle, hcamcorder->type);
529         }
530
531         ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PAUSED);
532         if (ret != MM_ERROR_NONE) {
533                 _mmcam_dbg_err("error : destroy pipeline");
534                 _mmcamcorder_destroy_pipeline(handle, hcamcorder->type);
535         }
536
537         ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
538         if (ret != MM_ERROR_NONE) {
539                 _mmcam_dbg_err("error : destroy pipeline");
540                 _mmcamcorder_destroy_pipeline(handle, hcamcorder->type);
541         }
542
543         /* set command function */
544         _mmcamcorder_set_state(handle, state_TO);
545 pipeline_creation_error:
546 _ERR_CAMCORDER_CMD:
547 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
548         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
549 _ERR_CAMCORDER_CMD_PRECON:
550         return ret;
551 }
552
553 int _mmcamcorder_mused_unrealize(MMHandleType handle)
554 {
555         int ret = MM_ERROR_NONE;
556         int state = MM_CAMCORDER_STATE_NONE;
557         int state_FROM = MM_CAMCORDER_STATE_READY;
558         int state_TO = MM_CAMCORDER_STATE_NULL;
559
560         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
561
562         _mmcam_dbg_log("");
563
564         if (!hcamcorder) {
565                 _mmcam_dbg_err("Not initialized");
566                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
567                 return ret;
568         }
569
570         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
571                 _mmcam_dbg_err("Another command is running.");
572                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
573                 goto _ERR_CAMCORDER_CMD_PRECON;
574         }
575
576         state = _mmcamcorder_get_state(handle);
577         if (state != state_FROM) {
578                 _mmcam_dbg_err("Wrong state(%d)", state);
579                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
580                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
581         }
582
583         /* Release SubContext */
584         if (hcamcorder->sub_context) {
585                 /* destroy pipeline */
586                 __mmcamcorder_mused_gst_destroy_pipeline(handle);
587                 /* Deallocate SubContext */
588                 _mmcamcorder_dealloc_subcontext(hcamcorder->sub_context);
589                 hcamcorder->sub_context = NULL;
590         }
591
592         /* Deinitialize main context member */
593         hcamcorder->command = NULL;
594
595         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
596
597         _mmcamcorder_set_state(handle, state_TO);
598
599         return MM_ERROR_NONE;
600
601 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
602         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
603
604 _ERR_CAMCORDER_CMD_PRECON:
605         /* send message */
606         _mmcam_dbg_err("Unrealize fail (type %d, state %d, ret %x)",
607                        hcamcorder->type, state, ret);
608
609         return ret;
610 }
611
612 int mm_camcorder_mused_unrealize(MMHandleType handle)
613 {
614         int ret = MM_ERROR_NONE;
615
616         ret = _mmcamcorder_mused_unrealize(handle);
617
618         return ret;
619 }
620
621 static int _mmcamcorder_get_video_caps(MMHandleType handle, char **caps)
622 {
623         int ret = MM_ERROR_NONE;
624         GstPad *pad = NULL;
625         GstCaps *sink_caps = NULL;
626
627         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
628         _MMCamcorderSubContext *sc = NULL;
629
630         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
631                 _mmcam_dbg_err("Another command is running.");
632                 return MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
633         }
634
635         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
636         _mmcam_dbg_log("Entered ");
637         pad = gst_element_get_static_pad(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, "sink");
638         if(!pad) {
639                 _mmcam_dbg_err("static pad is NULL");
640                 _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
641                 return MM_ERROR_CAMCORDER_INVALID_STATE;
642         }
643
644         sink_caps = gst_pad_get_current_caps(pad);
645         gst_object_unref( pad );
646         if(!sink_caps) {
647                 _mmcam_dbg_err("fail to get caps");
648                 _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
649                 return MM_ERROR_CAMCORDER_INVALID_STATE;
650         }
651
652         *caps = gst_caps_to_string(sink_caps);
653         _mmcam_dbg_err("video caps : %s", *caps);
654         gst_caps_unref(sink_caps);
655
656         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
657
658         return MM_ERROR_NONE;
659 }
660
661 int mm_camcorder_mused_get_video_caps(MMHandleType handle, char **caps)
662 {
663         return _mmcamcorder_get_video_caps(handle, caps);
664 }
665
666 static int _mmcamcorder_mused_set_shm_socket_path(MMHandleType handle, const char *path)
667 {
668         int ret = MM_ERROR_NONE;
669         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
670         _mmcam_dbg_log("aloc attribute handle : 0x%x, path:%s", handle, path);
671
672         _MMCAMCORDER_TRYLOCK_CMD(hcamcorder);
673
674         mm_camcorder_set_attributes(handle, NULL,
675                                     MMCAM_MUSED_DISPLAY_SHM_SOCKET_PATH, path, strlen(path),
676                                     NULL);
677
678         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
679
680         return ret;
681 }
682
683 /*
684  * Server and client both use functions
685  */
686 int mm_camcorder_mused_set_shm_socket_path(MMHandleType handle, const char *path)
687 {
688         int result = MM_ERROR_NONE;
689
690         _mmcam_dbg_log("Entered ");
691         result = _mmcamcorder_mused_set_shm_socket_path(handle, path);
692
693         return result;
694 }