1600e6df77d033662d9a17dac1db551d5de58765
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_client.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 |                                                                                                                                                                                       |
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_client.h"
44 #include "mm_camcorder_internal.h"
45 #include <sched.h>
46
47 bool _mmcamcorder_client_commit_display_handle(MMHandleType handle, int attr_idx, const mmf_value_t *value)
48 {
49         int current_state = MM_CAMCORDER_STATE_NONE;
50         const char *videosink_name = NULL;
51         void *p_handle = NULL;
52
53         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
54         _MMCamcorderSubContext *sc = NULL;
55
56         mmf_return_val_if_fail(handle, FALSE);
57
58         /* check type */
59         if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
60                 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
61                 return FALSE;
62         }
63
64         /* check current state */
65         current_state = _mmcamcorder_get_state(handle);
66         if (current_state < MM_CAMCORDER_STATE_READY) {
67                 _mmcam_dbg_log("NOT initialized. this will be applied later");
68                 return TRUE;
69         }
70
71         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
72
73         p_handle = value->value.p_val;
74         if (p_handle) {
75                 /* get videosink name */
76                 _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
77                 if (videosink_name == NULL) {
78                         _mmcam_dbg_err("Please check videosink element in configuration file");
79                         return FALSE;
80                 }
81
82                 _mmcam_dbg_log("Commit : videosinkname[%s]", videosink_name);
83
84                 if (!strcmp(videosink_name, "xvimagesink") ||
85                     !strcmp(videosink_name, "ximagesink")) {
86                         _mmcam_dbg_log("Commit : Set XID[%x]", *(int*)(p_handle));
87                         gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst), *(int*)(p_handle));
88                 } else if (!strcmp(videosink_name, "evasimagesink") ||
89                            !strcmp(videosink_name, "evaspixmapsink")) {
90                         _mmcam_dbg_log("Commit : Set evas object [%p]", p_handle);
91                         MMCAMCORDER_G_OBJECT_SET_POINTER(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, "evas-object", p_handle);
92 #ifdef HAVE_WAYLAND
93                 } else if (!strcmp(videosink_name, "waylandsink")) {
94                         MMCamWaylandInfo *wl_info = (MMCamWaylandInfo *)p_handle;
95                         GstContext *context = NULL;
96
97                         context = gst_wayland_display_handle_context_new((struct wl_display *)wl_info->display);
98                         if (context) {
99                                 gst_element_set_context(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, context);
100                         } else {
101                                 _mmcam_dbg_warn("gst_wayland_display_handle_context_new failed");
102                         }
103
104                         gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst), (guintptr)wl_info->surface);
105                         gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst),
106                                                                wl_info->window_x,
107                                                                wl_info->window_y,
108                                                                wl_info->window_width,
109                                                                wl_info->window_height);
110 #endif /* HAVE_WAYLAND */
111                 } else {
112                         _mmcam_dbg_warn("Commit : Nothing to commit with this element[%s]", videosink_name);
113                         return FALSE;
114                 }
115         } else {
116                 _mmcam_dbg_warn("Display handle is NULL");
117                 return FALSE;
118         }
119
120         return TRUE;
121 }
122
123 bool _mmcamcorder_client_commit_display_rect(MMHandleType handle, int attr_idx, const mmf_value_t *value)
124 {
125         int current_state = MM_CAMCORDER_STATE_NONE;
126         int method = 0;
127         const char *videosink_name = NULL;
128
129         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
130         _MMCamcorderSubContext *sc = NULL;
131
132         mmf_return_val_if_fail(handle, FALSE);
133
134         /* check type */
135         if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
136                 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
137                 return FALSE;
138         }
139
140         /* check current state */
141         current_state = _mmcamcorder_get_state(handle);
142         if (current_state < MM_CAMCORDER_STATE_READY) {
143                 _mmcam_dbg_log("NOT initialized. this will be applied later");
144                 return TRUE;
145         }
146
147         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
148
149         /* check current method */
150         mm_camcorder_get_attributes(handle, NULL,
151                                     MMCAM_DISPLAY_GEOMETRY_METHOD, &method,
152                                     NULL);
153         if (method != MM_DISPLAY_METHOD_CUSTOM_ROI) {
154                 _mmcam_dbg_log("current method[%d] is not supported rect", method);
155                 return FALSE;
156         }
157
158         /* Get videosink name */
159         _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
160         if (videosink_name == NULL) {
161                 _mmcam_dbg_err("Please check videosink element in configuration file");
162                 return FALSE;
163         }
164
165         if (!strcmp(videosink_name, "xvimagesink") ||
166             !strcmp(videosink_name, "evaspixmapsink")) {
167                 int rect_x = 0;
168                 int rect_y = 0;
169                 int rect_width = 0;
170                 int rect_height = 0;
171                 int flags = MM_ATTRS_FLAG_NONE;
172                 MMCamAttrsInfo info;
173
174                 mm_camcorder_get_attributes(handle, NULL,
175                                             MMCAM_DISPLAY_RECT_X, &rect_x,
176                                             MMCAM_DISPLAY_RECT_Y, &rect_y,
177                                             MMCAM_DISPLAY_RECT_WIDTH, &rect_width,
178                                             MMCAM_DISPLAY_RECT_HEIGHT, &rect_height,
179                                             NULL);
180                 switch (attr_idx) {
181                 case MM_CAM_CLIENT_DISPLAY_RECT_X:
182                         mm_camcorder_get_attribute_info(handle, MMCAM_DISPLAY_RECT_Y, &info);
183                         flags |= info.flag;
184                         memset(&info, 0x00, sizeof(info));
185                         mm_camcorder_get_attribute_info(handle, MMCAM_DISPLAY_RECT_WIDTH, &info);
186                         flags |= info.flag;
187                         memset(&info, 0x00, sizeof(info));
188                         mm_camcorder_get_attribute_info(handle, MMCAM_DISPLAY_RECT_HEIGHT, &info);
189                         flags |= info.flag;
190                         rect_x = value->value.i_val;
191                         break;
192                 case MM_CAM_CLIENT_DISPLAY_RECT_Y:
193                         mm_camcorder_get_attribute_info(handle, MMCAM_DISPLAY_RECT_WIDTH, &info);
194                         flags |= info.flag;
195                         memset(&info, 0x00, sizeof(info));
196                         mm_camcorder_get_attribute_info(handle, MMCAM_DISPLAY_RECT_HEIGHT, &info);
197                         flags |= info.flag;
198                         rect_y = value->value.i_val;
199                         break;
200                 case MM_CAM_CLIENT_DISPLAY_RECT_WIDTH:
201                         mm_camcorder_get_attribute_info(handle, MMCAM_DISPLAY_RECT_HEIGHT, &info);
202                         flags |= info.flag;
203                         rect_width = value->value.i_val;
204                         break;
205                 case MM_CAM_CLIENT_DISPLAY_RECT_HEIGHT:
206                         rect_height = value->value.i_val;
207                         break;
208                 default:
209                         _mmcam_dbg_err("Wrong attr_idx!");
210                         return FALSE;
211                 }
212
213                 if (!(flags & MM_ATTRS_FLAG_MODIFIED)) {
214                         _mmcam_dbg_log("RECT(x,y,w,h) = (%d,%d,%d,%d)",
215                                        rect_x, rect_y, rect_width, rect_height);
216                         g_object_set(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst,
217                                      "dst-roi-x", rect_x,
218                                      "dst-roi-y", rect_y,
219                                      "dst-roi-w", rect_width,
220                                      "dst-roi-h", rect_height,
221                                      NULL);
222                 }
223
224                 return TRUE;
225         } else {
226                 _mmcam_dbg_warn("videosink[%s] does not support display rect.", videosink_name);
227                 return FALSE;
228         }
229 }
230
231 bool _mmcamcorder_client_commit_display_rotation(MMHandleType handle, int attr_idx, const mmf_value_t *value)
232 {
233         int current_state = MM_CAMCORDER_STATE_NONE;
234
235         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
236
237         mmf_return_val_if_fail(handle, FALSE);
238
239         /* check type */
240         if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
241                 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
242                 return FALSE;
243         }
244
245         /* check current state */
246         current_state = _mmcamcorder_get_state(handle);
247         if (current_state < MM_CAMCORDER_STATE_READY) {
248                 _mmcam_dbg_log("NOT initialized. this will be applied later [rotate:%d]", value->value.i_val);
249                 return TRUE;
250         }
251
252         return _mmcamcorder_set_display_rotation(handle, value->value.i_val);
253 }
254
255 bool _mmcamcorder_client_commit_display_visible(MMHandleType handle, int attr_idx, const mmf_value_t *value)
256 {
257         int current_state = MM_CAMCORDER_STATE_NONE;
258         const char *videosink_name = NULL;
259
260         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
261         _MMCamcorderSubContext *sc = NULL;
262
263         mmf_return_val_if_fail(handle, FALSE);
264
265         /* check type */
266         if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
267                 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
268                 return FALSE;
269         }
270
271         /* check current state */
272         current_state = _mmcamcorder_get_state(handle);
273         if (current_state < MM_CAMCORDER_STATE_READY) {
274                 _mmcam_dbg_log("NOT initialized. this will be applied later");
275                 return TRUE;
276         }
277
278         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
279
280         /* Get videosink name */
281         _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
282         if (videosink_name == NULL) {
283                 _mmcam_dbg_err("Please check videosink element in configuration file");
284                 return FALSE;
285         }
286
287         if (!strcmp(videosink_name, "xvimagesink") || !strcmp(videosink_name, "evasimagesink") ||
288             !strcmp(videosink_name, "evaspixmapsink")) {
289                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, "visible", value->value.i_val);
290                 _mmcam_dbg_log("Set visible [%d] done.", value->value.i_val);
291                 return TRUE;
292         } else {
293                 _mmcam_dbg_warn("videosink[%s] does not support VISIBLE.", videosink_name);
294                 return FALSE;
295         }
296 }
297
298 bool _mmcamcorder_client_commit_display_geometry_method (MMHandleType handle, int attr_idx, const mmf_value_t *value)
299 {
300         int method = 0;
301         int current_state = MM_CAMCORDER_STATE_NONE;
302         const char *videosink_name = NULL;
303
304         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
305         _MMCamcorderSubContext *sc = NULL;
306
307         mmf_return_val_if_fail(handle, FALSE);
308
309         /* check type */
310         if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
311                 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
312                 return FALSE;
313         }
314
315         /* check current state */
316         current_state = _mmcamcorder_get_state(handle);
317         if (current_state < MM_CAMCORDER_STATE_READY) {
318                 _mmcam_dbg_log("NOT initialized. this will be applied later");
319                 return TRUE;
320         }
321
322         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
323
324         /* Get videosink name */
325         _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
326         if (videosink_name == NULL) {
327                 _mmcam_dbg_err("Please check videosink element in configuration file");
328                 return FALSE;
329         }
330
331         if (!strcmp(videosink_name, "xvimagesink") || !strcmp(videosink_name, "evasimagesink") ||
332             !strcmp(videosink_name, "evaspixmapsink")) {
333                 method = value->value.i_val;
334                 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, "display-geometry-method", method);
335                 return TRUE;
336         } else {
337                 _mmcam_dbg_warn("videosink[%s] does not support geometry method.", videosink_name);
338                 return FALSE;
339         }
340 }
341
342 bool _mmcamcorder_client_commit_display_scale(MMHandleType handle, int attr_idx, const mmf_value_t *value)
343 {
344         int zoom = 0;
345         int current_state = MM_CAMCORDER_STATE_NONE;
346         const char *videosink_name = NULL;
347         GstElement *vs_element = NULL;
348
349         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
350         _MMCamcorderSubContext *sc = NULL;
351
352         mmf_return_val_if_fail(handle, FALSE);
353
354         /* check type */
355         if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
356                 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
357                 return FALSE;
358         }
359
360         /* check current state */
361         current_state = _mmcamcorder_get_state(handle);
362         if (current_state < MM_CAMCORDER_STATE_READY) {
363                 _mmcam_dbg_log("NOT initialized. this will be applied later");
364                 return TRUE;
365         }
366
367         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
368
369         /* Get videosink name */
370         _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
371         if (videosink_name == NULL) {
372                 _mmcam_dbg_err("Please check videosink element in configuration file");
373                 return FALSE;
374         }
375
376         zoom = value->value.i_val;
377         if (!strcmp(videosink_name, "xvimagesink")) {
378                 vs_element = sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst;
379
380                 MMCAMCORDER_G_OBJECT_SET(vs_element, "zoom", (float)(zoom + 1));
381                 _mmcam_dbg_log("Set display zoom to %d", zoom + 1);
382
383                 return TRUE;
384         } else {
385                 _mmcam_dbg_warn("videosink[%s] does not support scale", videosink_name);
386                 return FALSE;
387         }
388 }
389
390 bool _mmcamcorder_client_commit_display_mode(MMHandleType handle, int attr_idx, const mmf_value_t *value)
391 {
392         int current_state = MM_CAMCORDER_STATE_NONE;
393         const char *videosink_name = NULL;
394
395         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
396         _MMCamcorderSubContext *sc = NULL;
397
398         mmf_return_val_if_fail(handle, FALSE);
399
400         /* check type */
401         if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
402                 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
403                 return FALSE;
404         }
405
406         /* check current state */
407         current_state = _mmcamcorder_get_state(handle);
408         if (current_state < MM_CAMCORDER_STATE_READY) {
409                 _mmcam_dbg_log("NOT initialized. this will be applied later");
410                 return TRUE;
411         }
412
413         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
414
415         _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
416         if (videosink_name == NULL) {
417                 _mmcam_dbg_err("Please check videosink element in configuration file");
418                 return FALSE;
419         }
420
421         _mmcam_dbg_log("Commit : videosinkname[%s]", videosink_name);
422
423         if (!strcmp(videosink_name, "xvimagesink")) {
424                 _mmcam_dbg_log("Commit : display mode [%d]", value->value.i_val);
425                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, "display-mode", value->value.i_val);
426                 return TRUE;
427         } else {
428                 _mmcam_dbg_warn("Commit : This element [%s] does not support display mode", videosink_name);
429                 return FALSE;
430         }
431 }
432
433 bool _mmcamcorder_client_commit_display_evas_do_scaling(MMHandleType handle, int attr_idx, const mmf_value_t *value)
434 {
435         int current_state = MM_CAMCORDER_STATE_NONE;
436         int do_scaling = 0;
437         const char *videosink_name = NULL;
438
439         mmf_camcorder_t *hcamcorder= MMF_CAMCORDER( handle);
440         _MMCamcorderSubContext *sc = NULL;
441
442         mmf_return_val_if_fail(handle, FALSE);
443
444         /* check type */
445         if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
446                 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
447                 return FALSE;
448         }
449
450         /* check current state */
451         current_state = _mmcamcorder_get_state(handle);
452         if (current_state < MM_CAMCORDER_STATE_READY) {
453                 _mmcam_dbg_log("NOT initialized. this will be applied later");
454                 return TRUE;
455         }
456
457         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
458
459         do_scaling = value->value.i_val;
460
461         /* Get videosink name */
462         _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
463         if (videosink_name == NULL) {
464                 _mmcam_dbg_err("Please check videosink element in configuration file");
465                 return FALSE;
466         }
467
468         if (!strcmp(videosink_name, "evaspixmapsink")) {
469                 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, "origin-size", !do_scaling);
470                 _mmcam_dbg_log("Set origin-size to %d", !(value->value.i_val));
471                 return TRUE;
472         } else {
473                 _mmcam_dbg_warn("videosink[%s] does not support scale", videosink_name);
474                 return FALSE;
475         }
476 }
477
478 bool _mmcamcorder_client_commit_display_flip(MMHandleType handle, int attr_idx, const mmf_value_t *value)
479 {
480         int current_state = MM_CAMCORDER_STATE_NONE;
481
482         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
483
484         mmf_return_val_if_fail(handle, FALSE);
485
486         /* check type */
487         if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
488                 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
489                 return FALSE;
490         }
491
492         /* check current state */
493         current_state = _mmcamcorder_get_state(handle);
494         if (current_state < MM_CAMCORDER_STATE_READY) {
495                 _mmcam_dbg_log("NOT initialized. this will be applied later [flip:%d]", value->value.i_val);
496                 return TRUE;
497         }
498
499         return _mmcamcorder_set_display_flip(handle, value->value.i_val);
500 }
501
502 int _mmcamcorder_client_videosink_window_set(MMHandleType handle, type_element* VideosinkElement)
503 {
504         int err = MM_ERROR_NONE;
505         int size = 0;
506         int retx = 0;
507         int rety = 0;
508         int retwidth = 0;
509         int retheight = 0;
510         int visible = 0;
511         int rotation = MM_DISPLAY_ROTATION_NONE;
512         int flip = MM_FLIP_NONE;
513         int display_mode = MM_DISPLAY_MODE_DEFAULT;
514         int display_geometry_method = MM_DISPLAY_METHOD_LETTER_BOX;
515         int origin_size = 0;
516         int zoom_attr = 0;
517         int zoom_level = 0;
518         int do_scaling = FALSE;
519         int *overlay = NULL;
520         gulong xid;
521         char *err_name = NULL;
522         const char *videosink_name = NULL;
523
524         GstElement *vsink = NULL;
525
526         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
527         _MMCamcorderSubContext *sc = NULL;
528
529         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
530         mmf_return_val_if_fail(VideosinkElement, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
531
532         _mmcam_dbg_log("");
533
534         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
535         mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
536         mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
537         mmf_return_val_if_fail(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
538
539         vsink = sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst;
540
541         /* Get video display information */
542         err = mm_camcorder_get_attributes(handle, &err_name,
543                                           MMCAM_DISPLAY_RECT_X, &retx,
544                                           MMCAM_DISPLAY_RECT_Y, &rety,
545                                           MMCAM_DISPLAY_RECT_WIDTH, &retwidth,
546                                           MMCAM_DISPLAY_RECT_HEIGHT, &retheight,
547                                           MMCAM_DISPLAY_ROTATION, &rotation,
548                                           MMCAM_DISPLAY_FLIP, &flip,
549                                           MMCAM_DISPLAY_VISIBLE, &visible,
550                                           MMCAM_DISPLAY_HANDLE, (void**)&overlay, &size,
551                                           MMCAM_DISPLAY_MODE, &display_mode,
552                                           MMCAM_DISPLAY_GEOMETRY_METHOD, &display_geometry_method,
553                                           MMCAM_DISPLAY_SCALE, &zoom_attr,
554                                           MMCAM_DISPLAY_EVAS_DO_SCALING, &do_scaling,
555                                           NULL);
556         if (err != MM_ERROR_NONE) {
557                 if (err_name) {
558                         _mmcam_dbg_err("failed to get attributes [%s][0x%x]", err_name, err);
559                         free(err_name);
560                         err_name = NULL;
561                 } else {
562                         _mmcam_dbg_err("failed to get attributes [0x%x]", err);
563                 }
564
565                 return err;
566         }
567
568         _mmcam_dbg_log("(overlay=%p, size=%d)", overlay, size);
569
570         _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
571
572         if (videosink_name == NULL) {
573                 _mmcam_dbg_err("videosink_name is empty");
574                 return MM_ERROR_CAMCORDER_INVALID_CONDITION;
575         }
576
577
578         /* Set display handle */
579         if (!strcmp(videosink_name, "xvimagesink") ||
580             !strcmp(videosink_name, "ximagesink")) {
581                 if (overlay) {
582                         xid = *overlay;
583                         _mmcam_dbg_log("xid = %lu )", xid);
584                         gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(vsink), xid);
585                 } else {
586                         _mmcam_dbg_warn("Handle is NULL. Set xid as 0.. but, it's not recommended.");
587                         gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(vsink), 0);
588                 }
589         } else if (!strcmp(videosink_name, "evasimagesink") ||
590                    !strcmp(videosink_name, "evaspixmapsink")) {
591                 _mmcam_dbg_log("videosink : %s, handle : %p", videosink_name, overlay);
592                 if (overlay) {
593                         MMCAMCORDER_G_OBJECT_SET_POINTER(vsink, "evas-object", overlay);
594                         MMCAMCORDER_G_OBJECT_SET(vsink, "origin-size", !do_scaling);
595                 } else {
596                         _mmcam_dbg_err("display handle(eavs object) is NULL");
597                         return MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
598                 }
599 #ifdef HAVE_WAYLAND
600         } else if (!strcmp(videosink_name, "waylandsink")) {
601                 MMCamWaylandInfo *wl_info = (MMCamWaylandInfo *)overlay;
602                 if (wl_info) {
603                         GstContext *context = NULL;
604
605                         context = gst_wayland_display_handle_context_new((struct wl_display *)wl_info->display);
606                         if (context) {
607                                 gst_element_set_context(vsink, context);
608                         } else {
609                                 _mmcam_dbg_warn("gst_wayland_display_handle_context_new failed");
610                         }
611
612                         gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(vsink), (guintptr)wl_info->surface);
613                         gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(vsink),
614                                                                wl_info->window_x,
615                                                                wl_info->window_y,
616                                                                wl_info->window_width,
617                                                                wl_info->window_height);
618                 } else {
619                         _mmcam_dbg_warn("Handle is NULL. skip setting.");
620                 }
621 #endif /* HAVE_WAYLAND */
622         } else {
623                 _mmcam_dbg_warn("Who are you?? (Videosink: %s)", videosink_name);
624         }
625
626         _mmcam_dbg_log("%s set: display_geometry_method[%d],origin-size[%d],visible[%d],rotate[%d],flip[%d]",
627                        videosink_name, display_geometry_method, origin_size, visible, rotation, flip);
628
629         /* Set attribute */
630         if (!strcmp(videosink_name, "xvimagesink") ||
631             !strcmp(videosink_name, "evaspixmapsink")) {
632                 /* set rotation */
633                 MMCAMCORDER_G_OBJECT_SET(vsink, "rotate", rotation);
634
635                 /* set flip */
636                 MMCAMCORDER_G_OBJECT_SET(vsink, "flip", flip);
637
638                 switch (zoom_attr) {
639                 case MM_DISPLAY_SCALE_DEFAULT:
640                         zoom_level = 1;
641                         break;
642                 case MM_DISPLAY_SCALE_DOUBLE_LENGTH:
643                         zoom_level = 2;
644                         break;
645                 case MM_DISPLAY_SCALE_TRIPLE_LENGTH:
646                         zoom_level = 3;
647                         break;
648                 default:
649                         _mmcam_dbg_warn("Unsupported zoom value. set as default.");
650                         zoom_level = 1;
651                         break;
652                 }
653
654                 MMCAMCORDER_G_OBJECT_SET(vsink, "display-geometry-method", display_geometry_method);
655                 MMCAMCORDER_G_OBJECT_SET(vsink, "display-mode", display_mode);
656                 MMCAMCORDER_G_OBJECT_SET(vsink, "visible", visible);
657                 MMCAMCORDER_G_OBJECT_SET(vsink, "zoom", zoom_level);
658
659                 if (display_geometry_method == MM_DISPLAY_METHOD_CUSTOM_ROI) {
660                         g_object_set(vsink,
661                                      "dst-roi-x", retx,
662                                      "dst-roi-y", rety,
663                                      "dst-roi-w", retwidth,
664                                      "dst-roi-h", retheight,
665                                      NULL);
666                 }
667         }
668
669         return MM_ERROR_NONE;
670 }
671
672 MMHandleType
673 _mmcamcorder_client_alloc_attribute(MMHandleType handle)
674 {
675         _mmcam_dbg_log( "" );
676
677         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
678         MMHandleType attrs = 0;
679         mmf_attrs_construct_info_t *attrs_const_info = NULL;
680         unsigned int attr_count = 0;
681         unsigned int idx;
682         static int visible_values[] = { 0, 1 }; /*0: off, 1:on*/
683
684         mmf_return_val_if_fail(hcamcorder, NULL);
685
686         /* Create attribute constructor */
687         _mmcam_dbg_log("start");
688
689         /* alloc 'mmf_attrs_construct_info_t' */
690         attr_count = MM_CAM_CLIENT_ATTRIBUTE_NUM;
691         attrs_const_info = malloc(attr_count * sizeof(mmf_attrs_construct_info_t));
692         if (!attrs_const_info) {
693                 _mmcam_dbg_err("Fail to alloc constructor.");
694                 return 0;
695         }
696
697         /* alloc default attribute info */
698         hcamcorder->cam_attrs_const_info = (mm_cam_attr_construct_info *)malloc(sizeof(mm_cam_attr_construct_info) * attr_count);
699         if (hcamcorder->cam_attrs_const_info == NULL) {
700                 _mmcam_dbg_err("failed to alloc default attribute info");
701                 free(attrs_const_info);
702                 attrs_const_info = NULL;
703                 return 0;
704         }
705
706         /* basic attributes' info */
707         mm_cam_attr_construct_info temp_info[] = {
708                 {
709                         MM_CAM_CLIENT_DISPLAY_SHM_SOCKET_PATH,
710                         MMCAM_DISPLAY_SHM_SOCKET_PATH,
711                         MMF_VALUE_TYPE_STRING,
712                         MM_ATTRS_FLAG_RW,
713                         {(void*)NULL},
714                         MM_ATTRS_VALID_TYPE_NONE,
715                         {0},
716                         {0},
717                         NULL,
718                 },
719                 {
720                         MM_CAM_CLIENT_DISPLAY_HANDLE,
721                         "display-handle",
722                         MMF_VALUE_TYPE_DATA,
723                         MM_ATTRS_FLAG_RW,
724                         {(void*)NULL},
725                         MM_ATTRS_VALID_TYPE_NONE,
726                         {0},
727                         {0},
728                         _mmcamcorder_client_commit_display_handle,
729                 },
730                 {
731                         MM_CAM_CLIENT_DISPLAY_DEVICE,
732                         "display-device",
733                         MMF_VALUE_TYPE_INT,
734                         MM_ATTRS_FLAG_RW,
735                         {(void*)MM_DISPLAY_DEVICE_MAINLCD},
736                         MM_ATTRS_VALID_TYPE_INT_ARRAY,
737                         {0},
738                         {0},
739                         NULL,
740                 },
741                 // 50
742                 {
743                         MM_CAM_CLIENT_DISPLAY_SURFACE,
744                         "display-surface",
745                         MMF_VALUE_TYPE_INT,
746                         MM_ATTRS_FLAG_RW,
747                         {(void*)MM_DISPLAY_SURFACE_X},
748                         MM_ATTRS_VALID_TYPE_INT_ARRAY,
749                         {0},
750                         {0},
751                         NULL,
752                 },
753                 {
754                         MM_CAM_CLIENT_DISPLAY_RECT_X,
755                         "display-rect-x",
756                         MMF_VALUE_TYPE_INT,
757                         MM_ATTRS_FLAG_RW,
758                         {(void*)0},
759                         MM_ATTRS_VALID_TYPE_INT_RANGE,
760                         {.int_min = 0},
761                         {.int_max = _MMCAMCORDER_MAX_INT},
762                         _mmcamcorder_client_commit_display_rect,
763                 },
764                 {
765                         MM_CAM_CLIENT_DISPLAY_RECT_Y,
766                         "display-rect-y",
767                         MMF_VALUE_TYPE_INT,
768                         MM_ATTRS_FLAG_RW,
769                         {(void*)0},
770                         MM_ATTRS_VALID_TYPE_INT_RANGE,
771                         {.int_min = 0},
772                         {.int_max = _MMCAMCORDER_MAX_INT},
773                         _mmcamcorder_client_commit_display_rect,
774                 },
775                 {
776                         MM_CAM_CLIENT_DISPLAY_RECT_WIDTH,
777                         "display-rect-width",
778                         MMF_VALUE_TYPE_INT,
779                         MM_ATTRS_FLAG_RW,
780                         {(void*)0},
781                         MM_ATTRS_VALID_TYPE_INT_RANGE,
782                         {.int_min = 0},
783                         {.int_max = _MMCAMCORDER_MAX_INT},
784                         _mmcamcorder_client_commit_display_rect,
785                 },
786                 {
787                         MM_CAM_CLIENT_DISPLAY_RECT_HEIGHT,
788                         "display-rect-height",
789                         MMF_VALUE_TYPE_INT,
790                         MM_ATTRS_FLAG_RW,
791                         {(void*)0},
792                         MM_ATTRS_VALID_TYPE_INT_RANGE,
793                         {.int_min = 0},
794                         {.int_max = _MMCAMCORDER_MAX_INT},
795                         _mmcamcorder_client_commit_display_rect,
796                 },
797                 {
798                         MM_CAM_CLIENT_DISPLAY_SOURCE_X,
799                         "display-src-x",
800                         MMF_VALUE_TYPE_INT,
801                         MM_ATTRS_FLAG_RW,
802                         {(void*)0},
803                         MM_ATTRS_VALID_TYPE_INT_RANGE,
804                         {.int_min = 0},
805                         {.int_max = _MMCAMCORDER_MAX_INT},
806                         NULL,
807                 },
808                 {
809                         MM_CAM_CLIENT_DISPLAY_SOURCE_Y,
810                         "display-src-y",
811                         MMF_VALUE_TYPE_INT,
812                         MM_ATTRS_FLAG_RW,
813                         {(void*)0},
814                         MM_ATTRS_VALID_TYPE_INT_RANGE,
815                         {.int_min = 0},
816                         {.int_max = _MMCAMCORDER_MAX_INT},
817                         NULL,
818                 },
819                 {
820                         MM_CAM_CLIENT_DISPLAY_SOURCE_WIDTH,
821                         "display-src-width",
822                         MMF_VALUE_TYPE_INT,
823                         MM_ATTRS_FLAG_RW,
824                         {(void*)0},
825                         MM_ATTRS_VALID_TYPE_INT_RANGE,
826                         {.int_min = 0},
827                         {.int_max = _MMCAMCORDER_MAX_INT},
828                         NULL,
829                 },
830                 {
831                         MM_CAM_CLIENT_DISPLAY_SOURCE_HEIGHT,
832                         "display-src-height",
833                         MMF_VALUE_TYPE_INT,
834                         MM_ATTRS_FLAG_RW,
835                         {(void*)0},
836                         MM_ATTRS_VALID_TYPE_INT_RANGE,
837                         {.int_min = 0},
838                         {.int_max = _MMCAMCORDER_MAX_INT},
839                         NULL,
840                 },
841                 {
842                         MM_CAM_CLIENT_DISPLAY_ROTATION,
843                         "display-rotation",
844                         MMF_VALUE_TYPE_INT,
845                         MM_ATTRS_FLAG_RW,
846                         {(void*)MM_DISPLAY_ROTATION_NONE},
847                         MM_ATTRS_VALID_TYPE_INT_RANGE,
848                         {.int_min = MM_DISPLAY_ROTATION_NONE},
849                         {.int_max = MM_DISPLAY_ROTATION_270},
850                         _mmcamcorder_client_commit_display_rotation,
851                 },
852                 { // 60
853                         MM_CAM_CLIENT_DISPLAY_VISIBLE,
854                         "display-visible",
855                         MMF_VALUE_TYPE_INT,
856                         MM_ATTRS_FLAG_RW,
857                         {(void*)1},
858                         MM_ATTRS_VALID_TYPE_INT_ARRAY,
859                         {visible_values},
860                         {ARRAY_SIZE(visible_values)},
861                         _mmcamcorder_client_commit_display_visible,
862                 },
863                 {
864                         MM_CAM_CLIENT_DISPLAY_SCALE,
865                         "display-scale",
866                         MMF_VALUE_TYPE_INT,
867                         MM_ATTRS_FLAG_RW,
868                         {(void*)0},
869                         MM_ATTRS_VALID_TYPE_INT_RANGE,
870                         {.int_min = MM_DISPLAY_SCALE_DEFAULT},
871                         {.int_max = MM_DISPLAY_SCALE_TRIPLE_LENGTH},
872                         _mmcamcorder_client_commit_display_scale,
873                 },
874                 {
875                         MM_CAM_CLIENT_DISPLAY_GEOMETRY_METHOD,
876                         "display-geometry-method",
877                         MMF_VALUE_TYPE_INT,
878                         MM_ATTRS_FLAG_RW,
879                         {(void*)0},
880                         MM_ATTRS_VALID_TYPE_INT_RANGE,
881                         {.int_min = MM_DISPLAY_METHOD_LETTER_BOX},
882                         {.int_max = MM_DISPLAY_METHOD_CUSTOM_ROI},
883                         _mmcamcorder_client_commit_display_geometry_method,
884                 },
885                 {
886                         MM_CAM_CLIENT_DISPLAY_MODE,
887                         "display-mode",
888                         MMF_VALUE_TYPE_INT,
889                         MM_ATTRS_FLAG_RW,
890                         {(void*)MM_DISPLAY_MODE_DEFAULT},
891                         MM_ATTRS_VALID_TYPE_INT_ARRAY,
892                         {0},
893                         {0},
894                         _mmcamcorder_client_commit_display_mode,
895                 },
896                 {
897                         MM_CAM_CLIENT_DISPLAY_EVAS_SURFACE_SINK,
898                         "display-evas-surface-sink",
899                         MMF_VALUE_TYPE_STRING,
900                         MM_ATTRS_FLAG_READABLE,
901                         {(void*)NULL},
902                         MM_ATTRS_VALID_TYPE_NONE,
903                         {0},
904                         {0},
905                         NULL,
906                 },
907                 {
908                         MM_CAM_CLIENT_DISPLAY_EVAS_DO_SCALING,
909                         "display-evas-do-scaling",
910                         MMF_VALUE_TYPE_INT,
911                         MM_ATTRS_FLAG_RW,
912                         {(void*)TRUE},
913                         MM_ATTRS_VALID_TYPE_INT_RANGE,
914                         {.int_min = FALSE},
915                         {.int_max = TRUE},
916                         _mmcamcorder_client_commit_display_evas_do_scaling,
917                 },
918                 {
919                         MM_CAM_CLIENT_DISPLAY_FLIP,
920                         "display-flip",
921                         MMF_VALUE_TYPE_INT,
922                         MM_ATTRS_FLAG_RW,
923                         {(void*)MM_FLIP_NONE},
924                         MM_ATTRS_VALID_TYPE_INT_RANGE,
925                         {.int_min = MM_FLIP_NONE},
926                         {.int_max = MM_FLIP_BOTH},
927                         _mmcamcorder_client_commit_display_flip,
928                 },
929         };
930
931         memcpy(hcamcorder->cam_attrs_const_info, temp_info, sizeof(mm_cam_attr_construct_info) * attr_count);
932
933         for (idx = 0 ; idx < attr_count ; idx++) {
934                 /* attribute order check. This should be same. */
935                 if (idx != hcamcorder->cam_attrs_const_info[idx].attrid) {
936                         _mmcam_dbg_err("Please check attributes order. Is the idx same with enum val?");
937                         free(attrs_const_info);
938                         attrs_const_info = NULL;
939                         free(hcamcorder->cam_attrs_const_info);
940                         hcamcorder->cam_attrs_const_info = NULL;
941                         return 0;
942                 }
943
944                 attrs_const_info[idx].name = hcamcorder->cam_attrs_const_info[idx].name;
945                 attrs_const_info[idx].value_type = hcamcorder->cam_attrs_const_info[idx].value_type;
946                 attrs_const_info[idx].flags = hcamcorder->cam_attrs_const_info[idx].flags;
947                 attrs_const_info[idx].default_value = hcamcorder->cam_attrs_const_info[idx].default_value.value_void;
948         }
949
950         /* Camcorder Attributes */
951         _mmcam_dbg_log("Create Camcorder Attributes[%p, %d]", attrs_const_info, attr_count);
952
953         attrs = mmf_attrs_new_from_data("Camcorder_Mused_Attributes",
954                                         attrs_const_info,
955                                         attr_count,
956                                         _mmcamcorder_commit_camcorder_attrs,
957                                         (void *)handle);
958
959         free(attrs_const_info);
960         attrs_const_info = NULL;
961
962         if (attrs == 0) {
963                 _mmcam_dbg_err("Fail to alloc attribute handle");
964                 free(hcamcorder->cam_attrs_const_info);
965                 hcamcorder->cam_attrs_const_info = NULL;
966                 return 0;
967         }
968
969         for (idx = 0; idx < attr_count; idx++)
970         {
971                 _mmcam_dbg_log("Valid type [%s]", hcamcorder->cam_attrs_const_info[idx].name);
972
973                 mmf_attrs_set_valid_type (attrs, idx, hcamcorder->cam_attrs_const_info[idx].validity_type);
974
975                 switch (hcamcorder->cam_attrs_const_info[idx].validity_type)
976                 {
977                         case MM_ATTRS_VALID_TYPE_INT_ARRAY:
978                                 if (hcamcorder->cam_attrs_const_info[idx].validity_value_1.int_array &&
979                                     hcamcorder->cam_attrs_const_info[idx].validity_value_2.count > 0) {
980                                         mmf_attrs_set_valid_array(attrs, idx,
981                                                                   (const int *)(hcamcorder->cam_attrs_const_info[idx].validity_value_1.int_array),
982                                                                   hcamcorder->cam_attrs_const_info[idx].validity_value_2.count,
983                                                                   hcamcorder->cam_attrs_const_info[idx].default_value.value_int);
984                                 }
985                         break;
986                         case MM_ATTRS_VALID_TYPE_INT_RANGE:
987                                 _mmcam_dbg_err("MM_ATTRS_VALID_TYPE_INT_RANGE");
988                                 mmf_attrs_set_valid_range(attrs, idx,
989                                                           hcamcorder->cam_attrs_const_info[idx].validity_value_1.int_min,
990                                                           hcamcorder->cam_attrs_const_info[idx].validity_value_2.int_max,
991                                                           hcamcorder->cam_attrs_const_info[idx].default_value.value_int);
992                         break;
993                         case MM_ATTRS_VALID_TYPE_DOUBLE_ARRAY:
994                                 if (hcamcorder->cam_attrs_const_info[idx].validity_value_1.double_array &&
995                                     hcamcorder->cam_attrs_const_info[idx].validity_value_2.count > 0) {
996                                         mmf_attrs_set_valid_double_array(attrs, idx,
997                                                                          (const double *)(hcamcorder->cam_attrs_const_info[idx].validity_value_1.double_array),
998                                                                          hcamcorder->cam_attrs_const_info[idx].validity_value_2.count,
999                                                                          hcamcorder->cam_attrs_const_info[idx].default_value.value_double);
1000                                 }
1001                         break;
1002                         case MM_ATTRS_VALID_TYPE_DOUBLE_RANGE:
1003                                 mmf_attrs_set_valid_double_range(attrs, idx,
1004                                                                  hcamcorder->cam_attrs_const_info[idx].validity_value_1.double_min,
1005                                                                  hcamcorder->cam_attrs_const_info[idx].validity_value_2.double_max,
1006                                                                  hcamcorder->cam_attrs_const_info[idx].default_value.value_double);
1007                         break;
1008                         case MM_ATTRS_VALID_TYPE_NONE:
1009                         break;
1010                         case MM_ATTRS_VALID_TYPE_INVALID:
1011                         default:
1012                                 _mmcam_dbg_err("Valid type error.");
1013                         break;
1014                 }
1015         }
1016
1017         return attrs;
1018 }
1019
1020 static gboolean
1021 __mmcamcorder_client_gstreamer_init(camera_conf * conf)
1022 {
1023         static const int max_argc = 10;
1024         int i = 0;
1025         int cnt_str = 0;
1026         gint *argc = NULL;
1027         gchar **argv = NULL;
1028         GError *err = NULL;
1029         gboolean ret = FALSE;
1030         type_string_array *GSTInitOption = NULL;
1031
1032         mmf_return_val_if_fail(conf, FALSE);
1033
1034         _mmcam_dbg_log("");
1035
1036         /* alloc */
1037         argc = malloc(sizeof(int));
1038         argv = malloc(sizeof(gchar *) * max_argc);
1039
1040         if (!argc || !argv) {
1041                 goto ERROR;
1042         }
1043
1044         memset(argv, 0, sizeof(gchar *) * max_argc);
1045
1046         /* add initial */
1047         *argc = 1;
1048         argv[0] = g_strdup("mmcamcorder");
1049
1050         /* add gst_param */
1051         _mmcamcorder_conf_get_value_string_array(conf,
1052                                                  CONFIGURE_CATEGORY_MAIN_GENERAL,
1053                                                  "GSTInitOption",
1054                                                  &GSTInitOption);
1055         if (GSTInitOption != NULL && GSTInitOption->value) {
1056                 cnt_str = GSTInitOption->count;
1057                 for( ; *argc < max_argc && *argc <= cnt_str ; (*argc)++ )
1058                 {
1059                         argv[*argc] = g_strdup(GSTInitOption->value[(*argc)-1]);
1060                 }
1061         }
1062
1063         _mmcam_dbg_log("initializing gstreamer with following parameter[argc:%d]", *argc);
1064
1065         for (i = 0; i < *argc; i++) {
1066                 _mmcam_dbg_log("argv[%d] : %s", i, argv[i]);
1067         }
1068
1069         /* initializing gstreamer */
1070         ret = gst_init_check (argc, &argv, &err);
1071         if (!ret) {
1072                 _mmcam_dbg_err("Could not initialize GStreamer: %s ",
1073                                err ? err->message : "unknown error occurred");
1074                 if (err) {
1075                         g_error_free (err);
1076                 }
1077         }
1078
1079         /* release */
1080         for (i = 0; i < *argc; i++) {
1081                 if (argv[i]) {
1082                         free(argv[i]);
1083                         argv[i] = NULL;
1084                 }
1085         }
1086
1087         if (argv) {
1088                 free(argv);
1089                 argv = NULL;
1090         }
1091
1092         if (argc) {
1093                 free(argc);
1094                 argc = NULL;
1095         }
1096
1097         return ret;
1098
1099 ERROR:
1100         _mmcam_dbg_err("failed to initialize gstreamer");
1101
1102         if (argv) {
1103                 free(argv);
1104                 argv = NULL;
1105         }
1106
1107         if (argc) {
1108                 free(argc);
1109                 argc = NULL;
1110         }
1111
1112         return FALSE;
1113 }
1114
1115 int _mmcamcorder_client_create_preview_elements(MMHandleType handle, const char *videosink_name, char *string_caps)
1116 {
1117         int ret = MM_ERROR_NONE;
1118         GList *element_list = NULL;
1119         GstElement *pipeline = NULL;
1120         char *socket_path = NULL;
1121         int socket_path_length;
1122         GstCaps *caps;
1123
1124         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1125         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1126         mmf_return_val_if_fail(hcamcorder->sub_context, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1127
1128         _MMCamcorderSubContext *sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1129
1130         /* create pipeline */
1131         _MMCAMCORDER_PIPELINE_MAKE(sc, sc->element, _MMCAMCORDER_CLIENT_MAIN_PIPE, "camera_client", ret);
1132
1133         /* create source */
1134         _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_CLIENT_VIDEOSRC_SRC, "shmsrc", "shmsrc", element_list, ret);
1135
1136         mm_camcorder_get_attributes(handle, NULL,
1137                                     MMCAM_DISPLAY_SHM_SOCKET_PATH, &socket_path, &socket_path_length,
1138                                     NULL);
1139
1140         if (socket_path == NULL ) {
1141                 _mmcam_dbg_err("shmsink's socket path is not set");
1142                 goto set_videosrc_error;
1143         }
1144
1145         _mmcam_dbg_err("shm src socket path : %s", socket_path);
1146
1147         g_object_set(sc->element[_MMCAMCORDER_CLIENT_VIDEOSRC_SRC].gst,
1148                         "socket-path", socket_path,
1149                         "is-live", TRUE,
1150                         NULL);
1151
1152         /* Making Video sink from here */
1153         _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_CLIENT_VIDEOSINK_QUE, "queue", "videosink_queue", element_list, ret);
1154
1155         /* Add color converting element */
1156         if (!strcmp(videosink_name, "evasimagesink") || !strcmp(videosink_name, "ximagesink")) {
1157                 _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_CLIENT_VIDEOSINK_CLS, "videoconvert", "videosrc_convert", element_list, ret);
1158         }
1159
1160         /* create sink */
1161         _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_CLIENT_VIDEOSINK_SINK, videosink_name, "videosink_sink", element_list, ret);
1162
1163         if (strcmp(videosink_name, "fakesink") != 0 && strcmp(videosink_name, "shmsink") != 0) {
1164
1165                 if (_mmcamcorder_client_videosink_window_set(handle, sc->VideosinkElement) != MM_ERROR_NONE) {
1166                         _mmcam_dbg_err("_mmcamcorder_videosink_window_set error");
1167                         ret = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
1168                         goto pipeline_creation_error;
1169                 }
1170         }
1171
1172         _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, sc->VideosinkElement);
1173
1174         /* add elements to main pipeline */
1175         if (!_mmcamcorder_add_elements_to_bin(GST_BIN(sc->element[_MMCAMCORDER_CLIENT_MAIN_PIPE].gst), element_list)) {
1176                 _mmcam_dbg_err("element_list add error.");
1177                 ret = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1178                 goto pipeline_creation_error;
1179         }
1180
1181         caps = gst_caps_from_string(string_caps);
1182         /* link elements */
1183         if (!_mmcamcorder_filtered_link_elements(element_list, caps)) {
1184                 _mmcam_dbg_err( "element link error." );
1185                 ret = MM_ERROR_CAMCORDER_GST_LINK;
1186                 goto pipeline_creation_error;
1187         }
1188
1189         pipeline = sc->element[_MMCAMCORDER_CLIENT_MAIN_PIPE].gst;
1190
1191         ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
1192         if (ret != MM_ERROR_NONE) {
1193                 _mmcam_dbg_err("error : destroy pipeline");
1194                 goto pipeline_creation_error;
1195         }
1196
1197         if (element_list) {
1198                 g_list_free(element_list);
1199                 element_list = NULL;
1200         }
1201
1202         return MM_ERROR_NONE;
1203
1204 pipeline_creation_error:
1205         _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_CLIENT_VIDEOSINK_SINK);
1206         if (!strcmp(videosink_name, "evasimagesink") || !strcmp(videosink_name, "ximagesink")) {
1207                 _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_CLIENT_VIDEOSINK_CLS);
1208         }
1209         _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_CLIENT_VIDEOSINK_QUE);
1210 set_videosrc_error:
1211         _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_CLIENT_VIDEOSRC_SRC);
1212         _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_CLIENT_MAIN_PIPE);
1213
1214         if (element_list) {
1215                 g_list_free(element_list);
1216                 element_list = NULL;
1217         }
1218
1219         return ret;
1220 }
1221
1222 void __mmcamcorder_client_gst_destroy_pipeline(MMHandleType handle)
1223 {
1224         _MMCamcorderSubContext *sc;
1225         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1226
1227         if (sc->element[_MMCAMCORDER_CLIENT_MAIN_PIPE].gst) {
1228                 _mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_CLIENT_MAIN_PIPE].gst, GST_STATE_NULL);
1229                 _mmcamcorder_remove_all_handlers(handle, _MMCAMCORDER_HANDLER_CATEGORY_ALL);
1230
1231                 gst_object_unref(sc->element[_MMCAMCORDER_CLIENT_MAIN_PIPE].gst);
1232         }
1233         return;
1234 }
1235
1236 int _mmcamcorder_client_realize(MMHandleType handle, char *string_caps)
1237 {
1238         int ret = MM_ERROR_NONE;
1239         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1240
1241         _MMCamcorderSubContext *sc;
1242         int display_surface_type = MM_DISPLAY_SURFACE_X;
1243         char *videosink_element_type = NULL;
1244         const char *videosink_name = NULL;
1245         char *err_name = NULL;
1246
1247         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1248         _mmcam_dbg_log("Enter");
1249
1250         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1251                 _mmcam_dbg_err("Another command is running.");
1252                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
1253                 goto _ERR_CAMCORDER_CMD_PRECON;
1254         }
1255
1256         /* alloc sub context */
1257         hcamcorder->sub_context = _mmcamcorder_alloc_subcontext(hcamcorder->type);
1258         if(!hcamcorder->sub_context) {
1259                 ret = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1260                 goto _ERR_CAMCORDER_CMD;
1261         }
1262
1263         sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1264
1265         ret = mm_camcorder_get_attributes(handle, &err_name,
1266                                     MMCAM_DISPLAY_SURFACE, &display_surface_type,
1267                                     NULL);
1268
1269         if (ret != MM_ERROR_NONE) {
1270                 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, ret);
1271                 SAFE_FREE(err_name);
1272                 goto _ERR_CAMCORDER_SET_DISPLAY;
1273         }
1274
1275         _mmcam_dbg_warn("display_surface_type : %d", display_surface_type);
1276
1277         switch (display_surface_type) {
1278         case MM_DISPLAY_SURFACE_X:
1279                 videosink_element_type = strdup("VideosinkElementX");
1280                 break;
1281         case MM_DISPLAY_SURFACE_EVAS:
1282                 videosink_element_type = strdup("VideosinkElementEvas");
1283                 break;
1284         case MM_DISPLAY_SURFACE_GL:
1285                 videosink_element_type = strdup("VideosinkElementGL");
1286                 break;
1287         case MM_DISPLAY_SURFACE_NULL:
1288                 videosink_element_type = strdup("VideosinkElementNull");
1289                 break;
1290         default:
1291                 videosink_element_type = strdup("VideosinkElementX");
1292                 break;
1293         }
1294
1295         /* check string of videosink element */
1296         if (videosink_element_type) {
1297                 _mmcamcorder_conf_get_element(handle, hcamcorder->conf_main,
1298                                               CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
1299                                               videosink_element_type,
1300                                               &sc->VideosinkElement);
1301                 free(videosink_element_type);
1302                 videosink_element_type = NULL;
1303         } else {
1304                 _mmcam_dbg_warn("strdup failed(display_surface_type %d). Use default X type",
1305                                 display_surface_type);
1306
1307                 _mmcamcorder_conf_get_element(handle, hcamcorder->conf_main,
1308                                               CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
1309                                               _MMCAMCORDER_DEFAULT_VIDEOSINK_TYPE,
1310                                               &sc->VideosinkElement);
1311         }
1312
1313         _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
1314
1315         if(videosink_name != NULL) {
1316                 _mmcam_dbg_log("Videosink name : %s", videosink_name);
1317                 ret = _mmcamcorder_client_create_preview_elements(handle, videosink_name, string_caps);
1318                 if (ret != MM_ERROR_NONE) {
1319                         _mmcam_dbg_err("create client's preview elements Failed.");
1320                         goto _ERR_CAMCORDER_SET_DISPLAY;
1321                 }
1322         } else {
1323                 _mmcam_dbg_err("Get Videosink name error");
1324                 goto _ERR_CAMCORDER_SET_DISPLAY;
1325         }
1326
1327         /* set command function */
1328         _mmcamcorder_set_state(handle, MM_CAMCORDER_STATE_READY);
1329
1330         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1331         return ret;
1332
1333 _ERR_CAMCORDER_SET_DISPLAY:
1334         if (hcamcorder->sub_context) {
1335                 _mmcamcorder_dealloc_subcontext(hcamcorder->sub_context);
1336                 hcamcorder->sub_context = NULL;
1337         }
1338 _ERR_CAMCORDER_CMD:
1339         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1340 _ERR_CAMCORDER_CMD_PRECON:
1341         return ret;
1342 }
1343
1344 int _mmcamcorder_client_unrealize(MMHandleType handle)
1345 {
1346         int ret = MM_ERROR_NONE;
1347         int state = MM_CAMCORDER_STATE_NONE;
1348         int state_FROM = MM_CAMCORDER_STATE_READY;
1349         int state_TO = MM_CAMCORDER_STATE_NULL;
1350
1351         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1352         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1353         _mmcam_dbg_log("Enter");
1354
1355         if (!hcamcorder) {
1356                 _mmcam_dbg_err("Not initialized");
1357                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
1358                 return ret;
1359         }
1360
1361         _mmcam_dbg_log("try lock");
1362         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1363                 _mmcam_dbg_err("Another command is running.");
1364                 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
1365                 goto _ERR_CAMCORDER_CMD_PRECON;
1366         }
1367
1368         state = _mmcamcorder_get_state(handle);
1369         if (state != state_FROM) {
1370                 _mmcam_dbg_err("Wrong state(%d)", state);
1371                 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
1372                 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1373         }
1374
1375         /* Release SubContext */
1376         if (hcamcorder->sub_context) {
1377                 /* destroy pipeline */
1378                 _mmcam_dbg_warn("destroy pipeline");
1379                 __mmcamcorder_client_gst_destroy_pipeline(handle);
1380                 /* Deallocate SubContext */
1381                 _mmcamcorder_dealloc_subcontext(hcamcorder->sub_context);
1382                 hcamcorder->sub_context = NULL;
1383         }
1384
1385         /* Deinitialize main context member */
1386         hcamcorder->command = NULL;
1387
1388         _mmcam_dbg_log("un lock");
1389         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1390
1391         _mmcamcorder_set_state(handle, state_TO);
1392
1393         return MM_ERROR_NONE;
1394
1395 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
1396         _mmcam_dbg_log("un lock");
1397         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1398
1399 _ERR_CAMCORDER_CMD_PRECON:
1400         /* send message */
1401         _mmcam_dbg_err("Unrealize fail (type %d, ret %x)",
1402                        hcamcorder->type, ret);
1403
1404         return ret;
1405 }
1406
1407 static int _mm_camcorder_client_set_shm_socket_path(MMHandleType handle, const char *path)
1408 {
1409         int ret = MM_ERROR_NONE;
1410         _mmcam_dbg_log("handle : 0x%x, path:%s", handle, path);
1411         mm_camcorder_set_attributes(handle, NULL,
1412                                     MMCAM_DISPLAY_SHM_SOCKET_PATH, path, strlen(path),
1413                                     NULL);
1414
1415         return ret;
1416 }
1417
1418 int mm_camcorder_client_create(MMHandleType *handle)
1419 {
1420         int ret = MM_ERROR_NONE;
1421         mmf_camcorder_t *hcamcorder = NULL;
1422
1423         _mmcam_dbg_log("Enter");
1424         mmf_return_val_if_fail(handle, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
1425
1426         /* Create mmf_camcorder_t handle and initialize every variable */
1427         hcamcorder = (mmf_camcorder_t *)malloc(sizeof(mmf_camcorder_t));
1428         mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_LOW_MEMORY);
1429         memset(hcamcorder, 0x00, sizeof(mmf_camcorder_t));
1430
1431         /* init values */
1432         hcamcorder->type = 0;
1433         hcamcorder->state = MM_CAMCORDER_STATE_NONE;
1434         hcamcorder->sub_context = NULL;
1435         hcamcorder->target_state = MM_CAMCORDER_STATE_NULL;
1436         hcamcorder->capture_in_recording = FALSE;
1437
1438         pthread_mutex_init(&((hcamcorder->mtsafe).lock), NULL);
1439         pthread_cond_init(&((hcamcorder->mtsafe).cond), NULL);
1440         pthread_mutex_init(&((hcamcorder->mtsafe).cmd_lock), NULL);
1441         pthread_mutex_init(&((hcamcorder->mtsafe).state_lock), NULL);
1442         pthread_mutex_init(&((hcamcorder->mtsafe).gst_state_lock), NULL);
1443         pthread_mutex_init(&((hcamcorder->mtsafe).message_cb_lock), NULL);
1444         pthread_mutex_init(&(hcamcorder->restart_preview_lock), NULL);
1445
1446         /* Get Camera Configure information from Camcorder INI file */
1447         _mmcamcorder_conf_get_info((MMHandleType)hcamcorder, CONFIGURE_TYPE_MAIN, CONFIGURE_MAIN_FILE, &hcamcorder->conf_main);
1448
1449         if (!(hcamcorder->conf_main)) {
1450                 _mmcam_dbg_err( "Failed to get configure(main) info." );
1451
1452                 ret = MM_ERROR_CAMCORDER_CREATE_CONFIGURE;
1453                 goto _ERR_CAMCORDER_CREATE_CONFIGURE;
1454         }
1455         _mmcam_dbg_log("aloc attribute handle : 0x%x", (MMHandleType)hcamcorder);
1456         hcamcorder->attributes = _mmcamcorder_client_alloc_attribute((MMHandleType)hcamcorder);
1457         if (!(hcamcorder->attributes)) {
1458                 _mmcam_dbg_err("_mmcamcorder_create::alloc attribute error.");
1459
1460                 ret = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1461                 goto _ERR_CAMCORDER_RESOURCE_CREATION;
1462         }
1463
1464         ret = __mmcamcorder_client_gstreamer_init(hcamcorder->conf_main);
1465         if (!ret) {
1466                 _mmcam_dbg_err( "Failed to initialize gstreamer!!" );
1467                 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
1468                 goto _ERR_DEFAULT_VALUE_INIT;
1469         }
1470
1471         /* Set initial state */
1472         _mmcamcorder_set_state((MMHandleType)hcamcorder, MM_CAMCORDER_STATE_NULL);
1473
1474         _mmcam_dbg_log("created handle %p", hcamcorder);
1475
1476         *handle = (MMHandleType)hcamcorder;
1477         _mmcam_dbg_log("created client handle : 0x%x", *handle);
1478
1479         return MM_ERROR_NONE;
1480
1481 _ERR_CAMCORDER_CREATE_CONFIGURE:
1482 _ERR_CAMCORDER_RESOURCE_CREATION:
1483 _ERR_DEFAULT_VALUE_INIT:
1484         /* Release lock, cond */
1485         pthread_mutex_destroy(&((hcamcorder->mtsafe).lock));
1486         pthread_cond_destroy(&((hcamcorder->mtsafe).cond));
1487         pthread_mutex_destroy(&((hcamcorder->mtsafe).cmd_lock));
1488         pthread_mutex_destroy(&((hcamcorder->mtsafe).state_lock));
1489         pthread_mutex_destroy(&((hcamcorder->mtsafe).gst_state_lock));
1490         pthread_mutex_destroy(&((hcamcorder->mtsafe).gst_encode_state_lock));
1491         pthread_mutex_destroy(&((hcamcorder->mtsafe).message_cb_lock));
1492
1493         pthread_mutex_destroy(&(hcamcorder->restart_preview_lock));
1494
1495         if (hcamcorder->conf_ctrl) {
1496                 _mmcamcorder_conf_release_info(handle, &hcamcorder->conf_ctrl);
1497         }
1498
1499         if (hcamcorder->conf_main) {
1500                 _mmcamcorder_conf_release_info(handle, &hcamcorder->conf_main);
1501         }
1502
1503         /* Release handle */
1504         memset(hcamcorder, 0x00, sizeof(mmf_camcorder_t));
1505         free(hcamcorder);
1506
1507         return ret;
1508 }
1509
1510 void mm_camcorder_client_destroy(MMHandleType handle)
1511 {
1512         mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1513
1514         _mmcam_dbg_log("try lock");
1515
1516         if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1517                 _mmcam_dbg_err("Another command is running.");
1518                 goto _ERR_CAMCORDER_CMD_PRECON;
1519         }
1520
1521         if (hcamcorder->attributes) {
1522                 _mmcamcorder_dealloc_attribute(handle, hcamcorder->attributes);
1523         }
1524
1525         _mmcam_dbg_log("unlock");
1526         _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1527
1528         pthread_mutex_destroy(&((hcamcorder->mtsafe).lock));
1529         pthread_cond_destroy(&((hcamcorder->mtsafe).cond));
1530         pthread_mutex_destroy(&((hcamcorder->mtsafe).cmd_lock));
1531         pthread_mutex_destroy(&((hcamcorder->mtsafe).state_lock));
1532         pthread_mutex_destroy(&((hcamcorder->mtsafe).gst_state_lock));
1533         pthread_mutex_destroy(&((hcamcorder->mtsafe).message_cb_lock));
1534         pthread_mutex_destroy(&(hcamcorder->restart_preview_lock));
1535         _mmcamcorder_set_state((MMHandleType)hcamcorder, MM_CAMCORDER_STATE_NONE);
1536         /* Release handle */
1537         memset(hcamcorder, 0x00, sizeof(mmf_camcorder_t));
1538         free(hcamcorder);
1539
1540 _ERR_CAMCORDER_CMD_PRECON:
1541         return;
1542 }
1543
1544 int mm_camcorder_client_realize(MMHandleType handle, char *caps)
1545 {
1546         int ret = MM_ERROR_NONE;
1547         ret = _mmcamcorder_client_realize(handle, caps);
1548         return ret;
1549 }
1550
1551 int mm_camcorder_client_unrealize(MMHandleType handle)
1552 {
1553         int ret = MM_ERROR_NONE;
1554         ret = _mmcamcorder_client_unrealize(handle);
1555         return ret;
1556 }
1557
1558 int mm_camcorder_client_set_shm_socket_path(MMHandleType handle, const char *path)
1559 {
1560         int ret = MM_ERROR_NONE;
1561         _mmcam_dbg_log("Entered ");
1562         ret = _mm_camcorder_client_set_shm_socket_path(handle, path);
1563         return ret;
1564 }