4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jeongmo Yang <jm80.yang@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 /*===========================================================================================
26 ========================================================================================== */
29 #include <gst/app/gstappsrc.h>
30 #include <gst/video/videooverlay.h>
32 #include <gst/wayland/wayland.h>
43 #include "mm_camcorder_client.h"
44 #include "mm_camcorder_internal.h"
50 static _MMCamcorderInfoConverting g_client_display_info[] = {
53 CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
54 MM_CAM_CLIENT_DISPLAY_DEVICE,
55 MM_CAMCORDER_ATTR_NONE,
57 MM_CAMCONVERT_TYPE_INT_ARRAY,
62 CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
63 MM_CAM_CLIENT_DISPLAY_MODE,
64 MM_CAMCORDER_ATTR_NONE,
66 MM_CAMCONVERT_TYPE_INT_ARRAY,
71 CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
72 MM_CAM_CLIENT_DISPLAY_SURFACE,
73 MM_CAMCORDER_ATTR_NONE,
75 MM_CAMCONVERT_TYPE_INT_ARRAY,
81 static int _storage_device_supported_cb(int storage_id, storage_type_e type, storage_state_e state, const char *path, void *user_data)
83 char **root_directory = (char **)user_data;
85 if (root_directory == NULL) {
86 _mmcam_dbg_warn("user data is NULL");
90 _mmcam_dbg_log("storage id %d, type %d, state %d, path %s",
91 storage_id, type, state, path ? path : "NULL");
93 if (type == STORAGE_TYPE_INTERNAL && path) {
94 if (*root_directory) {
95 free(*root_directory);
96 *root_directory = NULL;
99 *root_directory = strdup(path);
100 if (*root_directory) {
101 _mmcam_dbg_log("get root directory %s", *root_directory);
104 _mmcam_dbg_warn("strdup %s failed");
111 bool _mmcamcorder_client_commit_display_handle(MMHandleType handle, int attr_idx, const mmf_value_t *value)
113 int current_state = MM_CAMCORDER_STATE_NONE;
114 const char *videosink_name = NULL;
115 void *p_handle = NULL;
117 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
118 _MMCamcorderSubContext *sc = NULL;
120 mmf_return_val_if_fail(handle, FALSE);
123 if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
124 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
128 /* check current state */
129 current_state = _mmcamcorder_get_state(handle);
130 if (current_state < MM_CAMCORDER_STATE_READY) {
131 _mmcam_dbg_log("NOT initialized. this will be applied later");
135 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
137 p_handle = value->value.p_val;
139 /* get videosink name */
140 _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
141 if (videosink_name == NULL) {
142 _mmcam_dbg_err("Please check videosink element in configuration file");
146 _mmcam_dbg_log("Commit : videosinkname[%s]", videosink_name);
148 if (!strcmp(videosink_name, "xvimagesink") ||
149 !strcmp(videosink_name, "ximagesink")) {
150 _mmcam_dbg_log("Commit : Set XID[%x]", *(int*)(p_handle));
151 gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst), *(int*)(p_handle));
152 } else if (!strcmp(videosink_name, "evasimagesink") ||
153 !strcmp(videosink_name, "evaspixmapsink")) {
154 _mmcam_dbg_log("Commit : Set evas object [%p]", p_handle);
155 MMCAMCORDER_G_OBJECT_SET_POINTER(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, "evas-object", p_handle);
157 } else if (!strcmp(videosink_name, "waylandsink")) {
158 MMCamWaylandInfo *wl_info = (MMCamWaylandInfo *)p_handle;
159 GstContext *context = NULL;
161 context = gst_wayland_display_handle_context_new((struct wl_display *)wl_info->display);
163 gst_element_set_context(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, context);
165 _mmcam_dbg_warn("gst_wayland_display_handle_context_new failed");
168 gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst), (guintptr)wl_info->surface);
169 gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst),
172 wl_info->window_width,
173 wl_info->window_height);
174 #endif /* HAVE_WAYLAND */
176 _mmcam_dbg_warn("Commit : Nothing to commit with this element[%s]", videosink_name);
180 _mmcam_dbg_warn("Display handle is NULL");
187 bool _mmcamcorder_client_commit_display_rect(MMHandleType handle, int attr_idx, const mmf_value_t *value)
189 int current_state = MM_CAMCORDER_STATE_NONE;
191 const char *videosink_name = NULL;
193 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
194 _MMCamcorderSubContext *sc = NULL;
196 mmf_return_val_if_fail(handle, FALSE);
199 if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
200 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
204 /* check current state */
205 current_state = _mmcamcorder_get_state(handle);
206 if (current_state < MM_CAMCORDER_STATE_READY) {
207 _mmcam_dbg_log("NOT initialized. this will be applied later");
211 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
213 /* check current method */
214 mm_camcorder_get_attributes(handle, NULL,
215 MMCAM_DISPLAY_GEOMETRY_METHOD, &method,
217 if (method != MM_DISPLAY_METHOD_CUSTOM_ROI) {
218 _mmcam_dbg_log("current method[%d] is not supported rect", method);
222 /* Get videosink name */
223 _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
224 if (videosink_name == NULL) {
225 _mmcam_dbg_err("Please check videosink element in configuration file");
229 if (!strcmp(videosink_name, "xvimagesink") ||
230 !strcmp(videosink_name, "evaspixmapsink")) {
235 int flags = MM_ATTRS_FLAG_NONE;
238 mm_camcorder_get_attributes(handle, NULL,
239 MMCAM_DISPLAY_RECT_X, &rect_x,
240 MMCAM_DISPLAY_RECT_Y, &rect_y,
241 MMCAM_DISPLAY_RECT_WIDTH, &rect_width,
242 MMCAM_DISPLAY_RECT_HEIGHT, &rect_height,
245 case MM_CAM_CLIENT_DISPLAY_RECT_X:
246 mm_camcorder_get_attribute_info(handle, MMCAM_DISPLAY_RECT_Y, &info);
248 memset(&info, 0x00, sizeof(info));
249 mm_camcorder_get_attribute_info(handle, MMCAM_DISPLAY_RECT_WIDTH, &info);
251 memset(&info, 0x00, sizeof(info));
252 mm_camcorder_get_attribute_info(handle, MMCAM_DISPLAY_RECT_HEIGHT, &info);
254 rect_x = value->value.i_val;
256 case MM_CAM_CLIENT_DISPLAY_RECT_Y:
257 mm_camcorder_get_attribute_info(handle, MMCAM_DISPLAY_RECT_WIDTH, &info);
259 memset(&info, 0x00, sizeof(info));
260 mm_camcorder_get_attribute_info(handle, MMCAM_DISPLAY_RECT_HEIGHT, &info);
262 rect_y = value->value.i_val;
264 case MM_CAM_CLIENT_DISPLAY_RECT_WIDTH:
265 mm_camcorder_get_attribute_info(handle, MMCAM_DISPLAY_RECT_HEIGHT, &info);
267 rect_width = value->value.i_val;
269 case MM_CAM_CLIENT_DISPLAY_RECT_HEIGHT:
270 rect_height = value->value.i_val;
273 _mmcam_dbg_err("Wrong attr_idx!");
277 if (!(flags & MM_ATTRS_FLAG_MODIFIED)) {
278 _mmcam_dbg_log("RECT(x,y,w,h) = (%d,%d,%d,%d)",
279 rect_x, rect_y, rect_width, rect_height);
280 g_object_set(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst,
283 "dst-roi-w", rect_width,
284 "dst-roi-h", rect_height,
290 _mmcam_dbg_warn("videosink[%s] does not support display rect.", videosink_name);
295 bool _mmcamcorder_client_commit_display_rotation(MMHandleType handle, int attr_idx, const mmf_value_t *value)
297 int current_state = MM_CAMCORDER_STATE_NONE;
299 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
301 mmf_return_val_if_fail(handle, FALSE);
304 if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
305 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
309 /* check current state */
310 current_state = _mmcamcorder_get_state(handle);
311 if (current_state < MM_CAMCORDER_STATE_READY) {
312 _mmcam_dbg_log("NOT initialized. this will be applied later [rotate:%d]", value->value.i_val);
316 return _mmcamcorder_set_display_rotation(handle, value->value.i_val);
319 bool _mmcamcorder_client_commit_display_visible(MMHandleType handle, int attr_idx, const mmf_value_t *value)
321 int current_state = MM_CAMCORDER_STATE_NONE;
322 const char *videosink_name = NULL;
324 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
325 _MMCamcorderSubContext *sc = NULL;
327 mmf_return_val_if_fail(handle, FALSE);
330 if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
331 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
335 /* check current state */
336 current_state = _mmcamcorder_get_state(handle);
337 if (current_state < MM_CAMCORDER_STATE_READY) {
338 _mmcam_dbg_log("NOT initialized. this will be applied later");
342 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
344 /* Get videosink name */
345 _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
346 if (videosink_name == NULL) {
347 _mmcam_dbg_err("Please check videosink element in configuration file");
351 if (!strcmp(videosink_name, "xvimagesink") || !strcmp(videosink_name, "evasimagesink") ||
352 !strcmp(videosink_name, "evaspixmapsink")) {
353 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, "visible", value->value.i_val);
354 _mmcam_dbg_log("Set visible [%d] done.", value->value.i_val);
357 _mmcam_dbg_warn("videosink[%s] does not support VISIBLE.", videosink_name);
362 bool _mmcamcorder_client_commit_display_geometry_method (MMHandleType handle, int attr_idx, const mmf_value_t *value)
365 int current_state = MM_CAMCORDER_STATE_NONE;
366 const char *videosink_name = NULL;
368 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
369 _MMCamcorderSubContext *sc = NULL;
371 mmf_return_val_if_fail(handle, FALSE);
374 if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
375 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
379 /* check current state */
380 current_state = _mmcamcorder_get_state(handle);
381 if (current_state < MM_CAMCORDER_STATE_READY) {
382 _mmcam_dbg_log("NOT initialized. this will be applied later");
386 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
388 /* Get videosink name */
389 _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
390 if (videosink_name == NULL) {
391 _mmcam_dbg_err("Please check videosink element in configuration file");
395 if (!strcmp(videosink_name, "xvimagesink") || !strcmp(videosink_name, "evasimagesink") ||
396 !strcmp(videosink_name, "evaspixmapsink")) {
397 method = value->value.i_val;
398 MMCAMCORDER_G_OBJECT_SET( sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, "display-geometry-method", method);
401 _mmcam_dbg_warn("videosink[%s] does not support geometry method.", videosink_name);
406 bool _mmcamcorder_client_commit_display_scale(MMHandleType handle, int attr_idx, const mmf_value_t *value)
409 int current_state = MM_CAMCORDER_STATE_NONE;
410 const char *videosink_name = NULL;
411 GstElement *vs_element = NULL;
413 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
414 _MMCamcorderSubContext *sc = NULL;
416 mmf_return_val_if_fail(handle, FALSE);
419 if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
420 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
424 /* check current state */
425 current_state = _mmcamcorder_get_state(handle);
426 if (current_state < MM_CAMCORDER_STATE_READY) {
427 _mmcam_dbg_log("NOT initialized. this will be applied later");
431 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
433 /* Get videosink name */
434 _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
435 if (videosink_name == NULL) {
436 _mmcam_dbg_err("Please check videosink element in configuration file");
440 zoom = value->value.i_val;
441 if (!strcmp(videosink_name, "xvimagesink")) {
442 vs_element = sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst;
444 MMCAMCORDER_G_OBJECT_SET(vs_element, "zoom", (float)(zoom + 1));
445 _mmcam_dbg_log("Set display zoom to %d", zoom + 1);
449 _mmcam_dbg_warn("videosink[%s] does not support scale", videosink_name);
454 bool _mmcamcorder_client_commit_display_mode(MMHandleType handle, int attr_idx, const mmf_value_t *value)
456 int current_state = MM_CAMCORDER_STATE_NONE;
457 const char *videosink_name = NULL;
459 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
460 _MMCamcorderSubContext *sc = NULL;
462 mmf_return_val_if_fail(handle, FALSE);
465 if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
466 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
470 /* check current state */
471 current_state = _mmcamcorder_get_state(handle);
472 if (current_state < MM_CAMCORDER_STATE_READY) {
473 _mmcam_dbg_log("NOT initialized. this will be applied later");
477 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
479 _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
480 if (videosink_name == NULL) {
481 _mmcam_dbg_err("Please check videosink element in configuration file");
485 _mmcam_dbg_log("Commit : videosinkname[%s]", videosink_name);
487 if (!strcmp(videosink_name, "xvimagesink")) {
488 _mmcam_dbg_log("Commit : display mode [%d]", value->value.i_val);
489 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, "display-mode", value->value.i_val);
492 _mmcam_dbg_warn("Commit : This element [%s] does not support display mode", videosink_name);
497 bool _mmcamcorder_client_commit_display_evas_do_scaling(MMHandleType handle, int attr_idx, const mmf_value_t *value)
499 int current_state = MM_CAMCORDER_STATE_NONE;
501 const char *videosink_name = NULL;
503 mmf_camcorder_t *hcamcorder= MMF_CAMCORDER( handle);
504 _MMCamcorderSubContext *sc = NULL;
506 mmf_return_val_if_fail(handle, FALSE);
509 if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
510 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
514 /* check current state */
515 current_state = _mmcamcorder_get_state(handle);
516 if (current_state < MM_CAMCORDER_STATE_READY) {
517 _mmcam_dbg_log("NOT initialized. this will be applied later");
521 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
523 do_scaling = value->value.i_val;
525 /* Get videosink name */
526 _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
527 if (videosink_name == NULL) {
528 _mmcam_dbg_err("Please check videosink element in configuration file");
532 if (!strcmp(videosink_name, "evaspixmapsink")) {
533 MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, "origin-size", !do_scaling);
534 _mmcam_dbg_log("Set origin-size to %d", !(value->value.i_val));
537 _mmcam_dbg_warn("videosink[%s] does not support scale", videosink_name);
542 bool _mmcamcorder_client_commit_display_flip(MMHandleType handle, int attr_idx, const mmf_value_t *value)
544 int current_state = MM_CAMCORDER_STATE_NONE;
546 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
548 mmf_return_val_if_fail(handle, FALSE);
551 if (hcamcorder->type == MM_CAMCORDER_MODE_AUDIO) {
552 _mmcam_dbg_err("invalid mode %d", hcamcorder->type);
556 /* check current state */
557 current_state = _mmcamcorder_get_state(handle);
558 if (current_state < MM_CAMCORDER_STATE_READY) {
559 _mmcam_dbg_log("NOT initialized. this will be applied later [flip:%d]", value->value.i_val);
563 return _mmcamcorder_set_display_flip(handle, value->value.i_val);
566 int _mmcamcorder_client_videosink_window_set(MMHandleType handle, type_element* VideosinkElement)
568 int err = MM_ERROR_NONE;
575 int rotation = MM_DISPLAY_ROTATION_NONE;
576 int flip = MM_FLIP_NONE;
577 int display_mode = MM_DISPLAY_MODE_DEFAULT;
578 int display_geometry_method = MM_DISPLAY_METHOD_LETTER_BOX;
582 int do_scaling = FALSE;
585 char *err_name = NULL;
586 const char *videosink_name = NULL;
588 GstElement *vsink = NULL;
590 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
591 _MMCamcorderSubContext *sc = NULL;
593 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
594 mmf_return_val_if_fail(VideosinkElement, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
598 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
599 mmf_return_val_if_fail(sc, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
600 mmf_return_val_if_fail(sc->element, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
601 mmf_return_val_if_fail(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
603 vsink = sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst;
605 /* Get video display information */
606 err = mm_camcorder_get_attributes(handle, &err_name,
607 MMCAM_DISPLAY_RECT_X, &retx,
608 MMCAM_DISPLAY_RECT_Y, &rety,
609 MMCAM_DISPLAY_RECT_WIDTH, &retwidth,
610 MMCAM_DISPLAY_RECT_HEIGHT, &retheight,
611 MMCAM_DISPLAY_ROTATION, &rotation,
612 MMCAM_DISPLAY_FLIP, &flip,
613 MMCAM_DISPLAY_VISIBLE, &visible,
614 MMCAM_DISPLAY_HANDLE, (void**)&overlay, &size,
615 MMCAM_DISPLAY_MODE, &display_mode,
616 MMCAM_DISPLAY_GEOMETRY_METHOD, &display_geometry_method,
617 MMCAM_DISPLAY_SCALE, &zoom_attr,
618 MMCAM_DISPLAY_EVAS_DO_SCALING, &do_scaling,
620 if (err != MM_ERROR_NONE) {
622 _mmcam_dbg_err("failed to get attributes [%s][0x%x]", err_name, err);
626 _mmcam_dbg_err("failed to get attributes [0x%x]", err);
632 _mmcam_dbg_log("(overlay=%p, size=%d)", overlay, size);
634 _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
636 if (videosink_name == NULL) {
637 _mmcam_dbg_err("videosink_name is empty");
638 return MM_ERROR_CAMCORDER_INVALID_CONDITION;
642 /* Set display handle */
643 if (!strcmp(videosink_name, "xvimagesink") ||
644 !strcmp(videosink_name, "ximagesink")) {
647 _mmcam_dbg_log("xid = %lu )", xid);
648 gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(vsink), xid);
650 _mmcam_dbg_warn("Handle is NULL. Set xid as 0.. but, it's not recommended.");
651 gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(vsink), 0);
653 } else if (!strcmp(videosink_name, "evasimagesink") ||
654 !strcmp(videosink_name, "evaspixmapsink")) {
655 _mmcam_dbg_log("videosink : %s, handle : %p", videosink_name, overlay);
657 MMCAMCORDER_G_OBJECT_SET_POINTER(vsink, "evas-object", overlay);
658 MMCAMCORDER_G_OBJECT_SET(vsink, "origin-size", !do_scaling);
660 _mmcam_dbg_err("display handle(eavs object) is NULL");
661 return MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
664 } else if (!strcmp(videosink_name, "waylandsink")) {
665 MMCamWaylandInfo *wl_info = (MMCamWaylandInfo *)overlay;
667 GstContext *context = NULL;
669 context = gst_wayland_display_handle_context_new((struct wl_display *)wl_info->display);
671 gst_element_set_context(vsink, context);
673 _mmcam_dbg_warn("gst_wayland_display_handle_context_new failed");
676 gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(vsink), (guintptr)wl_info->surface);
677 gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(vsink),
680 wl_info->window_width,
681 wl_info->window_height);
683 _mmcam_dbg_warn("Handle is NULL. skip setting.");
685 #endif /* HAVE_WAYLAND */
687 _mmcam_dbg_warn("Who are you?? (Videosink: %s)", videosink_name);
690 _mmcam_dbg_log("%s set: display_geometry_method[%d],origin-size[%d],visible[%d],rotate[%d],flip[%d]",
691 videosink_name, display_geometry_method, origin_size, visible, rotation, flip);
694 if (!strcmp(videosink_name, "xvimagesink") ||
695 !strcmp(videosink_name, "evaspixmapsink")) {
697 MMCAMCORDER_G_OBJECT_SET(vsink, "rotate", rotation);
700 MMCAMCORDER_G_OBJECT_SET(vsink, "flip", flip);
703 case MM_DISPLAY_SCALE_DEFAULT:
706 case MM_DISPLAY_SCALE_DOUBLE_LENGTH:
709 case MM_DISPLAY_SCALE_TRIPLE_LENGTH:
713 _mmcam_dbg_warn("Unsupported zoom value. set as default.");
718 MMCAMCORDER_G_OBJECT_SET(vsink, "display-geometry-method", display_geometry_method);
719 MMCAMCORDER_G_OBJECT_SET(vsink, "display-mode", display_mode);
720 MMCAMCORDER_G_OBJECT_SET(vsink, "visible", visible);
721 MMCAMCORDER_G_OBJECT_SET(vsink, "zoom", zoom_level);
723 if (display_geometry_method == MM_DISPLAY_METHOD_CUSTOM_ROI) {
727 "dst-roi-w", retwidth,
728 "dst-roi-h", retheight,
733 return MM_ERROR_NONE;
736 int _mmcamcorder_client_init_attr_from_configure(MMHandleType handle)
738 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
739 _MMCamcorderInfoConverting *info = NULL;
742 int ret = MM_ERROR_NONE;
744 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
746 /* Initialize attribute related to display */
747 info = g_client_display_info;
748 table_size = sizeof(g_client_display_info) / sizeof(_MMCamcorderInfoConverting);
749 ret = __mmcamcorder_set_info_to_attr(handle, info, table_size);
750 if (ret != MM_ERROR_NONE) {
751 _mmcam_dbg_err("display info set error : 0x%x", ret);
755 _mmcam_dbg_log("done");
760 MMHandleType _mmcamcorder_client_alloc_attribute(MMHandleType handle)
762 _mmcam_dbg_log( "" );
764 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
765 MMHandleType attrs = 0;
766 mmf_attrs_construct_info_t *attrs_const_info = NULL;
767 unsigned int attr_count = 0;
769 static int visible_values[] = { 0, 1 }; /*0: off, 1:on*/
771 mmf_return_val_if_fail(hcamcorder, NULL);
773 /* Create attribute constructor */
774 _mmcam_dbg_log("start");
776 /* alloc 'mmf_attrs_construct_info_t' */
777 attr_count = MM_CAM_CLIENT_ATTRIBUTE_NUM;
778 attrs_const_info = malloc(attr_count * sizeof(mmf_attrs_construct_info_t));
779 if (!attrs_const_info) {
780 _mmcam_dbg_err("Fail to alloc constructor.");
784 /* alloc default attribute info */
785 hcamcorder->cam_attrs_const_info = (mm_cam_attr_construct_info *)malloc(sizeof(mm_cam_attr_construct_info) * attr_count);
786 if (hcamcorder->cam_attrs_const_info == NULL) {
787 _mmcam_dbg_err("failed to alloc default attribute info");
788 free(attrs_const_info);
789 attrs_const_info = NULL;
793 /* basic attributes' info */
794 mm_cam_attr_construct_info temp_info[] = {
796 MM_CAM_CLIENT_DISPLAY_SHM_SOCKET_PATH,
797 MMCAM_DISPLAY_SHM_SOCKET_PATH,
798 MMF_VALUE_TYPE_STRING,
801 MM_ATTRS_VALID_TYPE_NONE,
807 MM_CAM_CLIENT_DISPLAY_HANDLE,
812 MM_ATTRS_VALID_TYPE_NONE,
815 _mmcamcorder_client_commit_display_handle,
818 MM_CAM_CLIENT_DISPLAY_DEVICE,
822 {(void*)MM_DISPLAY_DEVICE_MAINLCD},
823 MM_ATTRS_VALID_TYPE_INT_ARRAY,
830 MM_CAM_CLIENT_DISPLAY_SURFACE,
834 {(void*)MM_DISPLAY_SURFACE_X},
835 MM_ATTRS_VALID_TYPE_INT_ARRAY,
841 MM_CAM_CLIENT_DISPLAY_RECT_X,
846 MM_ATTRS_VALID_TYPE_INT_RANGE,
848 {.int_max = _MMCAMCORDER_MAX_INT},
849 _mmcamcorder_client_commit_display_rect,
852 MM_CAM_CLIENT_DISPLAY_RECT_Y,
857 MM_ATTRS_VALID_TYPE_INT_RANGE,
859 {.int_max = _MMCAMCORDER_MAX_INT},
860 _mmcamcorder_client_commit_display_rect,
863 MM_CAM_CLIENT_DISPLAY_RECT_WIDTH,
864 "display-rect-width",
868 MM_ATTRS_VALID_TYPE_INT_RANGE,
870 {.int_max = _MMCAMCORDER_MAX_INT},
871 _mmcamcorder_client_commit_display_rect,
874 MM_CAM_CLIENT_DISPLAY_RECT_HEIGHT,
875 "display-rect-height",
879 MM_ATTRS_VALID_TYPE_INT_RANGE,
881 {.int_max = _MMCAMCORDER_MAX_INT},
882 _mmcamcorder_client_commit_display_rect,
885 MM_CAM_CLIENT_DISPLAY_SOURCE_X,
890 MM_ATTRS_VALID_TYPE_INT_RANGE,
892 {.int_max = _MMCAMCORDER_MAX_INT},
896 MM_CAM_CLIENT_DISPLAY_SOURCE_Y,
901 MM_ATTRS_VALID_TYPE_INT_RANGE,
903 {.int_max = _MMCAMCORDER_MAX_INT},
907 MM_CAM_CLIENT_DISPLAY_SOURCE_WIDTH,
912 MM_ATTRS_VALID_TYPE_INT_RANGE,
914 {.int_max = _MMCAMCORDER_MAX_INT},
918 MM_CAM_CLIENT_DISPLAY_SOURCE_HEIGHT,
919 "display-src-height",
923 MM_ATTRS_VALID_TYPE_INT_RANGE,
925 {.int_max = _MMCAMCORDER_MAX_INT},
929 MM_CAM_CLIENT_DISPLAY_ROTATION,
933 {(void*)MM_DISPLAY_ROTATION_NONE},
934 MM_ATTRS_VALID_TYPE_INT_RANGE,
935 {.int_min = MM_DISPLAY_ROTATION_NONE},
936 {.int_max = MM_DISPLAY_ROTATION_270},
937 _mmcamcorder_client_commit_display_rotation,
940 MM_CAM_CLIENT_DISPLAY_VISIBLE,
945 MM_ATTRS_VALID_TYPE_INT_ARRAY,
947 {ARRAY_SIZE(visible_values)},
948 _mmcamcorder_client_commit_display_visible,
951 MM_CAM_CLIENT_DISPLAY_SCALE,
956 MM_ATTRS_VALID_TYPE_INT_RANGE,
957 {.int_min = MM_DISPLAY_SCALE_DEFAULT},
958 {.int_max = MM_DISPLAY_SCALE_TRIPLE_LENGTH},
959 _mmcamcorder_client_commit_display_scale,
962 MM_CAM_CLIENT_DISPLAY_GEOMETRY_METHOD,
963 "display-geometry-method",
967 MM_ATTRS_VALID_TYPE_INT_RANGE,
968 {.int_min = MM_DISPLAY_METHOD_LETTER_BOX},
969 {.int_max = MM_DISPLAY_METHOD_CUSTOM_ROI},
970 _mmcamcorder_client_commit_display_geometry_method,
973 MM_CAM_CLIENT_DISPLAY_MODE,
977 {(void*)MM_DISPLAY_MODE_DEFAULT},
978 MM_ATTRS_VALID_TYPE_INT_ARRAY,
981 _mmcamcorder_client_commit_display_mode,
984 MM_CAM_CLIENT_DISPLAY_EVAS_SURFACE_SINK,
985 "display-evas-surface-sink",
986 MMF_VALUE_TYPE_STRING,
987 MM_ATTRS_FLAG_READABLE,
989 MM_ATTRS_VALID_TYPE_NONE,
995 MM_CAM_CLIENT_DISPLAY_EVAS_DO_SCALING,
996 "display-evas-do-scaling",
1000 MM_ATTRS_VALID_TYPE_INT_RANGE,
1003 _mmcamcorder_client_commit_display_evas_do_scaling,
1006 MM_CAM_CLIENT_DISPLAY_FLIP,
1010 {(void*)MM_FLIP_NONE},
1011 MM_ATTRS_VALID_TYPE_INT_RANGE,
1012 {.int_min = MM_FLIP_NONE},
1013 {.int_max = MM_FLIP_BOTH},
1014 _mmcamcorder_client_commit_display_flip,
1018 memcpy(hcamcorder->cam_attrs_const_info, temp_info, sizeof(mm_cam_attr_construct_info) * attr_count);
1020 for (idx = 0 ; idx < attr_count ; idx++) {
1021 /* attribute order check. This should be same. */
1022 if (idx != hcamcorder->cam_attrs_const_info[idx].attrid) {
1023 _mmcam_dbg_err("Please check attributes order. Is the idx same with enum val?");
1024 free(attrs_const_info);
1025 attrs_const_info = NULL;
1026 free(hcamcorder->cam_attrs_const_info);
1027 hcamcorder->cam_attrs_const_info = NULL;
1031 attrs_const_info[idx].name = hcamcorder->cam_attrs_const_info[idx].name;
1032 attrs_const_info[idx].value_type = hcamcorder->cam_attrs_const_info[idx].value_type;
1033 attrs_const_info[idx].flags = hcamcorder->cam_attrs_const_info[idx].flags;
1034 attrs_const_info[idx].default_value = hcamcorder->cam_attrs_const_info[idx].default_value.value_void;
1037 /* Camcorder Attributes */
1038 _mmcam_dbg_log("Create Camcorder Attributes[%p, %d]", attrs_const_info, attr_count);
1040 attrs = mmf_attrs_new_from_data("Camcorder_Mused_Attributes",
1043 _mmcamcorder_commit_camcorder_attrs,
1046 free(attrs_const_info);
1047 attrs_const_info = NULL;
1050 _mmcam_dbg_err("Fail to alloc attribute handle");
1051 free(hcamcorder->cam_attrs_const_info);
1052 hcamcorder->cam_attrs_const_info = NULL;
1056 for (idx = 0; idx < attr_count; idx++)
1058 _mmcam_dbg_log("Valid type [%s]", hcamcorder->cam_attrs_const_info[idx].name);
1060 mmf_attrs_set_valid_type (attrs, idx, hcamcorder->cam_attrs_const_info[idx].validity_type);
1062 switch (hcamcorder->cam_attrs_const_info[idx].validity_type)
1064 case MM_ATTRS_VALID_TYPE_INT_ARRAY:
1065 if (hcamcorder->cam_attrs_const_info[idx].validity_value_1.int_array &&
1066 hcamcorder->cam_attrs_const_info[idx].validity_value_2.count > 0) {
1067 mmf_attrs_set_valid_array(attrs, idx,
1068 (const int *)(hcamcorder->cam_attrs_const_info[idx].validity_value_1.int_array),
1069 hcamcorder->cam_attrs_const_info[idx].validity_value_2.count,
1070 hcamcorder->cam_attrs_const_info[idx].default_value.value_int);
1073 case MM_ATTRS_VALID_TYPE_INT_RANGE:
1074 _mmcam_dbg_err("MM_ATTRS_VALID_TYPE_INT_RANGE");
1075 mmf_attrs_set_valid_range(attrs, idx,
1076 hcamcorder->cam_attrs_const_info[idx].validity_value_1.int_min,
1077 hcamcorder->cam_attrs_const_info[idx].validity_value_2.int_max,
1078 hcamcorder->cam_attrs_const_info[idx].default_value.value_int);
1080 case MM_ATTRS_VALID_TYPE_DOUBLE_ARRAY:
1081 if (hcamcorder->cam_attrs_const_info[idx].validity_value_1.double_array &&
1082 hcamcorder->cam_attrs_const_info[idx].validity_value_2.count > 0) {
1083 mmf_attrs_set_valid_double_array(attrs, idx,
1084 (const double *)(hcamcorder->cam_attrs_const_info[idx].validity_value_1.double_array),
1085 hcamcorder->cam_attrs_const_info[idx].validity_value_2.count,
1086 hcamcorder->cam_attrs_const_info[idx].default_value.value_double);
1089 case MM_ATTRS_VALID_TYPE_DOUBLE_RANGE:
1090 mmf_attrs_set_valid_double_range(attrs, idx,
1091 hcamcorder->cam_attrs_const_info[idx].validity_value_1.double_min,
1092 hcamcorder->cam_attrs_const_info[idx].validity_value_2.double_max,
1093 hcamcorder->cam_attrs_const_info[idx].default_value.value_double);
1095 case MM_ATTRS_VALID_TYPE_NONE:
1097 case MM_ATTRS_VALID_TYPE_INVALID:
1099 _mmcam_dbg_err("Valid type error.");
1108 __mmcamcorder_client_gstreamer_init(camera_conf * conf)
1110 static const int max_argc = 10;
1114 gchar **argv = NULL;
1116 gboolean ret = FALSE;
1117 type_string_array *GSTInitOption = NULL;
1119 mmf_return_val_if_fail(conf, FALSE);
1124 argc = malloc(sizeof(int));
1125 argv = malloc(sizeof(gchar *) * max_argc);
1127 if (!argc || !argv) {
1131 memset(argv, 0, sizeof(gchar *) * max_argc);
1135 argv[0] = g_strdup("mmcamcorder");
1138 _mmcamcorder_conf_get_value_string_array(conf,
1139 CONFIGURE_CATEGORY_MAIN_GENERAL,
1142 if (GSTInitOption != NULL && GSTInitOption->value) {
1143 cnt_str = GSTInitOption->count;
1144 for( ; *argc < max_argc && *argc <= cnt_str ; (*argc)++ )
1146 argv[*argc] = g_strdup(GSTInitOption->value[(*argc)-1]);
1150 _mmcam_dbg_log("initializing gstreamer with following parameter[argc:%d]", *argc);
1152 for (i = 0; i < *argc; i++) {
1153 _mmcam_dbg_log("argv[%d] : %s", i, argv[i]);
1156 /* initializing gstreamer */
1157 ret = gst_init_check (argc, &argv, &err);
1159 _mmcam_dbg_err("Could not initialize GStreamer: %s ",
1160 err ? err->message : "unknown error occurred");
1167 for (i = 0; i < *argc; i++) {
1183 _mmcam_dbg_err("failed to initialize gstreamer");
1198 int _mmcamcorder_client_create_preview_elements(MMHandleType handle, const char *videosink_name, char *string_caps)
1200 int ret = MM_ERROR_NONE;
1201 GList *element_list = NULL;
1202 GstElement *pipeline = NULL;
1203 char *socket_path = NULL;
1204 int socket_path_length;
1207 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1208 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1209 mmf_return_val_if_fail(hcamcorder->sub_context, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1211 _MMCamcorderSubContext *sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1213 /* create pipeline */
1214 _MMCAMCORDER_PIPELINE_MAKE(sc, sc->element, _MMCAMCORDER_CLIENT_MAIN_PIPE, "camera_client", ret);
1217 _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_CLIENT_VIDEOSRC_SRC, "shmsrc", "shmsrc", element_list, ret);
1219 mm_camcorder_get_attributes(handle, NULL,
1220 MMCAM_DISPLAY_SHM_SOCKET_PATH, &socket_path, &socket_path_length,
1223 if (socket_path == NULL ) {
1224 _mmcam_dbg_err("shmsink's socket path is not set");
1225 goto set_videosrc_error;
1228 _mmcam_dbg_err("shm src socket path : %s", socket_path);
1230 g_object_set(sc->element[_MMCAMCORDER_CLIENT_VIDEOSRC_SRC].gst,
1231 "socket-path", socket_path,
1235 /* create capsfilter */
1236 _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_CLIENT_VIDEOSRC_FILT, "capsfilter", "vidoesrc_filt", element_list, ret);
1238 caps = gst_caps_from_string(string_caps);
1239 MMCAMCORDER_G_OBJECT_SET_POINTER(sc->element[_MMCAMCORDER_CLIENT_VIDEOSRC_FILT].gst, "caps", caps);
1241 gst_caps_unref(caps);
1245 /* Making Video sink from here */
1246 _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_CLIENT_VIDEOSINK_QUE, "queue", "videosink_queue", element_list, ret);
1248 /* Add color converting element */
1249 if (!strcmp(videosink_name, "evasimagesink") || !strcmp(videosink_name, "ximagesink")) {
1250 _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_CLIENT_VIDEOSINK_CLS, "videoconvert", "videosrc_convert", element_list, ret);
1254 _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_CLIENT_VIDEOSINK_SINK, videosink_name, "videosink_sink", element_list, ret);
1256 if (strcmp(videosink_name, "fakesink") != 0 && strcmp(videosink_name, "shmsink") != 0) {
1258 if (_mmcamcorder_client_videosink_window_set(handle, sc->VideosinkElement) != MM_ERROR_NONE) {
1259 _mmcam_dbg_err("_mmcamcorder_videosink_window_set error");
1260 ret = MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
1261 goto pipeline_creation_error;
1265 _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_CLIENT_VIDEOSINK_SINK].gst, sc->VideosinkElement);
1267 /* add elements to main pipeline */
1268 if (!_mmcamcorder_add_elements_to_bin(GST_BIN(sc->element[_MMCAMCORDER_CLIENT_MAIN_PIPE].gst), element_list)) {
1269 _mmcam_dbg_err("element_list add error.");
1270 ret = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1271 goto pipeline_creation_error;
1275 if (!_mmcamcorder_link_elements(element_list)) {
1276 _mmcam_dbg_err( "element link error." );
1277 ret = MM_ERROR_CAMCORDER_GST_LINK;
1278 goto pipeline_creation_error;
1281 pipeline = sc->element[_MMCAMCORDER_CLIENT_MAIN_PIPE].gst;
1283 ret = _mmcamcorder_gst_set_state(handle, pipeline, GST_STATE_PLAYING);
1284 if (ret != MM_ERROR_NONE) {
1285 _mmcam_dbg_err("error : destroy pipeline");
1286 goto pipeline_creation_error;
1290 g_list_free(element_list);
1291 element_list = NULL;
1294 return MM_ERROR_NONE;
1296 pipeline_creation_error:
1297 _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_CLIENT_VIDEOSINK_SINK);
1298 if (!strcmp(videosink_name, "evasimagesink") || !strcmp(videosink_name, "ximagesink")) {
1299 _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_CLIENT_VIDEOSINK_CLS);
1301 _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_CLIENT_VIDEOSINK_QUE);
1303 _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_CLIENT_VIDEOSRC_SRC);
1304 _MMCAMCORDER_ELEMENT_REMOVE(sc->element, _MMCAMCORDER_CLIENT_MAIN_PIPE);
1307 g_list_free(element_list);
1308 element_list = NULL;
1314 void __mmcamcorder_client_gst_destroy_pipeline(MMHandleType handle)
1316 _MMCamcorderSubContext *sc;
1317 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1319 if (sc->element[_MMCAMCORDER_CLIENT_MAIN_PIPE].gst) {
1320 _mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_CLIENT_MAIN_PIPE].gst, GST_STATE_NULL);
1321 _mmcamcorder_remove_all_handlers(handle, _MMCAMCORDER_HANDLER_CATEGORY_ALL);
1323 gst_object_unref(sc->element[_MMCAMCORDER_CLIENT_MAIN_PIPE].gst);
1328 int _mmcamcorder_client_realize(MMHandleType handle, char *string_caps)
1330 int ret = MM_ERROR_NONE;
1331 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1333 _MMCamcorderSubContext *sc;
1334 int display_surface_type = MM_DISPLAY_SURFACE_X;
1335 char *videosink_element_type = NULL;
1336 const char *videosink_name = NULL;
1337 char *err_name = NULL;
1339 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1340 _mmcam_dbg_log("Enter");
1342 if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1343 _mmcam_dbg_err("Another command is running.");
1344 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
1345 goto _ERR_CAMCORDER_CMD_PRECON;
1348 /* alloc sub context */
1349 hcamcorder->sub_context = _mmcamcorder_alloc_subcontext(hcamcorder->type);
1350 if(!hcamcorder->sub_context) {
1351 ret = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1352 goto _ERR_CAMCORDER_CMD;
1355 sc = MMF_CAMCORDER_SUBCONTEXT(handle);
1357 ret = mm_camcorder_get_attributes(handle, &err_name,
1358 MMCAM_DISPLAY_SURFACE, &display_surface_type,
1361 if (ret != MM_ERROR_NONE) {
1362 _mmcam_dbg_warn("Get attrs fail. (%s:%x)", err_name, ret);
1363 SAFE_FREE(err_name);
1364 goto _ERR_CAMCORDER_SET_DISPLAY;
1367 _mmcam_dbg_warn("display_surface_type : %d", display_surface_type);
1369 switch (display_surface_type) {
1370 case MM_DISPLAY_SURFACE_X:
1371 videosink_element_type = strdup("VideosinkElementX");
1373 case MM_DISPLAY_SURFACE_EVAS:
1374 videosink_element_type = strdup("VideosinkElementEvas");
1376 case MM_DISPLAY_SURFACE_GL:
1377 videosink_element_type = strdup("VideosinkElementGL");
1379 case MM_DISPLAY_SURFACE_NULL:
1380 videosink_element_type = strdup("VideosinkElementNull");
1383 videosink_element_type = strdup("VideosinkElementX");
1387 /* check string of videosink element */
1388 if (videosink_element_type) {
1389 _mmcamcorder_conf_get_element(handle, hcamcorder->conf_main,
1390 CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
1391 videosink_element_type,
1392 &sc->VideosinkElement);
1393 free(videosink_element_type);
1394 videosink_element_type = NULL;
1396 _mmcam_dbg_warn("strdup failed(display_surface_type %d). Use default X type",
1397 display_surface_type);
1399 _mmcamcorder_conf_get_element(handle, hcamcorder->conf_main,
1400 CONFIGURE_CATEGORY_MAIN_VIDEO_OUTPUT,
1401 _MMCAMCORDER_DEFAULT_VIDEOSINK_TYPE,
1402 &sc->VideosinkElement);
1405 _mmcamcorder_conf_get_value_element_name(sc->VideosinkElement, &videosink_name);
1407 if(videosink_name != NULL) {
1408 _mmcam_dbg_log("Videosink name : %s", videosink_name);
1409 ret = _mmcamcorder_client_create_preview_elements(handle, videosink_name, string_caps);
1410 if (ret != MM_ERROR_NONE) {
1411 _mmcam_dbg_err("create client's preview elements Failed.");
1412 goto _ERR_CAMCORDER_SET_DISPLAY;
1415 _mmcam_dbg_err("Get Videosink name error");
1416 goto _ERR_CAMCORDER_SET_DISPLAY;
1419 /* set command function */
1420 _mmcamcorder_set_state(handle, MM_CAMCORDER_STATE_READY);
1422 _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1425 _ERR_CAMCORDER_SET_DISPLAY:
1426 if (hcamcorder->sub_context) {
1427 _mmcamcorder_dealloc_subcontext(hcamcorder->sub_context);
1428 hcamcorder->sub_context = NULL;
1431 _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1432 _ERR_CAMCORDER_CMD_PRECON:
1436 int _mmcamcorder_client_unrealize(MMHandleType handle)
1438 int ret = MM_ERROR_NONE;
1439 int state = MM_CAMCORDER_STATE_NONE;
1440 int state_FROM = MM_CAMCORDER_STATE_READY;
1441 int state_TO = MM_CAMCORDER_STATE_NULL;
1443 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1444 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_NOT_INITIALIZED);
1445 _mmcam_dbg_log("Enter");
1448 _mmcam_dbg_err("Not initialized");
1449 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
1453 _mmcam_dbg_log("try lock");
1454 if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1455 _mmcam_dbg_err("Another command is running.");
1456 ret = MM_ERROR_CAMCORDER_CMD_IS_RUNNING;
1457 goto _ERR_CAMCORDER_CMD_PRECON;
1460 state = _mmcamcorder_get_state(handle);
1461 if (state != state_FROM) {
1462 _mmcam_dbg_err("Wrong state(%d)", state);
1463 ret = MM_ERROR_CAMCORDER_INVALID_STATE;
1464 goto _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK;
1467 /* Release SubContext */
1468 if (hcamcorder->sub_context) {
1469 /* destroy pipeline */
1470 _mmcam_dbg_warn("destroy pipeline");
1471 __mmcamcorder_client_gst_destroy_pipeline(handle);
1472 /* Deallocate SubContext */
1473 _mmcamcorder_dealloc_subcontext(hcamcorder->sub_context);
1474 hcamcorder->sub_context = NULL;
1477 /* Deinitialize main context member */
1478 hcamcorder->command = NULL;
1480 _mmcam_dbg_log("un lock");
1481 _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1483 _mmcamcorder_set_state(handle, state_TO);
1485 return MM_ERROR_NONE;
1487 _ERR_CAMCORDER_CMD_PRECON_AFTER_LOCK:
1488 _mmcam_dbg_log("un lock");
1489 _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1491 _ERR_CAMCORDER_CMD_PRECON:
1493 _mmcam_dbg_err("Unrealize fail (type %d, ret %x)",
1494 hcamcorder->type, ret);
1499 static int _mm_camcorder_client_set_shm_socket_path(MMHandleType handle, const char *path)
1501 int ret = MM_ERROR_NONE;
1502 _mmcam_dbg_log("handle : 0x%x, path:%s", handle, path);
1503 mm_camcorder_set_attributes(handle, NULL,
1504 MMCAM_DISPLAY_SHM_SOCKET_PATH, path, strlen(path),
1510 int mm_camcorder_client_create(MMHandleType *handle)
1512 int ret = MM_ERROR_NONE;
1513 mmf_camcorder_t *hcamcorder = NULL;
1515 _mmcam_dbg_log("Enter");
1516 mmf_return_val_if_fail(handle, MM_ERROR_CAMCORDER_INVALID_ARGUMENT);
1518 /* Create mmf_camcorder_t handle and initialize every variable */
1519 hcamcorder = (mmf_camcorder_t *)malloc(sizeof(mmf_camcorder_t));
1520 mmf_return_val_if_fail(hcamcorder, MM_ERROR_CAMCORDER_LOW_MEMORY);
1521 memset(hcamcorder, 0x00, sizeof(mmf_camcorder_t));
1524 hcamcorder->type = 0;
1525 hcamcorder->state = MM_CAMCORDER_STATE_NONE;
1526 hcamcorder->sub_context = NULL;
1527 hcamcorder->target_state = MM_CAMCORDER_STATE_NULL;
1528 hcamcorder->capture_in_recording = FALSE;
1530 pthread_mutex_init(&((hcamcorder->mtsafe).lock), NULL);
1531 pthread_cond_init(&((hcamcorder->mtsafe).cond), NULL);
1532 pthread_mutex_init(&((hcamcorder->mtsafe).cmd_lock), NULL);
1533 pthread_mutex_init(&((hcamcorder->mtsafe).state_lock), NULL);
1534 pthread_mutex_init(&((hcamcorder->mtsafe).gst_state_lock), NULL);
1535 pthread_mutex_init(&((hcamcorder->mtsafe).message_cb_lock), NULL);
1536 pthread_mutex_init(&(hcamcorder->restart_preview_lock), NULL);
1538 /* Get Camera Configure information from Camcorder INI file */
1539 _mmcamcorder_conf_get_info((MMHandleType)hcamcorder, CONFIGURE_TYPE_MAIN, CONFIGURE_MAIN_FILE, &hcamcorder->conf_main);
1541 if (!(hcamcorder->conf_main)) {
1542 _mmcam_dbg_err( "Failed to get configure(main) info." );
1544 ret = MM_ERROR_CAMCORDER_CREATE_CONFIGURE;
1545 goto _ERR_CAMCORDER_CREATE_CONFIGURE;
1547 _mmcam_dbg_log("aloc attribute handle : 0x%x", (MMHandleType)hcamcorder);
1548 hcamcorder->attributes = _mmcamcorder_client_alloc_attribute((MMHandleType)hcamcorder);
1549 if (!(hcamcorder->attributes)) {
1550 _mmcam_dbg_err("_mmcamcorder_create::alloc attribute error.");
1552 ret = MM_ERROR_CAMCORDER_RESOURCE_CREATION;
1553 goto _ERR_CAMCORDER_RESOURCE_CREATION;
1556 ret = __mmcamcorder_client_gstreamer_init(hcamcorder->conf_main);
1558 _mmcam_dbg_err( "Failed to initialize gstreamer!!" );
1559 ret = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
1560 goto _ERR_DEFAULT_VALUE_INIT;
1563 ret = _mmcamcorder_client_init_attr_from_configure((MMHandleType)hcamcorder);
1564 if (ret != MM_ERROR_NONE) {
1565 _mmcam_dbg_warn("client_init_attr_from_configure error!!");
1566 ret = MM_ERROR_CAMCORDER_INTERNAL;
1567 goto _ERR_DEFAULT_VALUE_INIT;
1570 /* Set initial state */
1571 _mmcamcorder_set_state((MMHandleType)hcamcorder, MM_CAMCORDER_STATE_NULL);
1573 _mmcam_dbg_log("created handle %p", hcamcorder);
1575 *handle = (MMHandleType)hcamcorder;
1576 _mmcam_dbg_log("created client handle : 0x%x", *handle);
1578 return MM_ERROR_NONE;
1580 _ERR_CAMCORDER_CREATE_CONFIGURE:
1581 _ERR_CAMCORDER_RESOURCE_CREATION:
1582 _ERR_DEFAULT_VALUE_INIT:
1583 /* Release lock, cond */
1584 pthread_mutex_destroy(&((hcamcorder->mtsafe).lock));
1585 pthread_cond_destroy(&((hcamcorder->mtsafe).cond));
1586 pthread_mutex_destroy(&((hcamcorder->mtsafe).cmd_lock));
1587 pthread_mutex_destroy(&((hcamcorder->mtsafe).state_lock));
1588 pthread_mutex_destroy(&((hcamcorder->mtsafe).gst_state_lock));
1589 pthread_mutex_destroy(&((hcamcorder->mtsafe).gst_encode_state_lock));
1590 pthread_mutex_destroy(&((hcamcorder->mtsafe).message_cb_lock));
1592 pthread_mutex_destroy(&(hcamcorder->restart_preview_lock));
1594 if (hcamcorder->conf_ctrl) {
1595 _mmcamcorder_conf_release_info(handle, &hcamcorder->conf_ctrl);
1598 if (hcamcorder->conf_main) {
1599 _mmcamcorder_conf_release_info(handle, &hcamcorder->conf_main);
1602 /* Release handle */
1603 memset(hcamcorder, 0x00, sizeof(mmf_camcorder_t));
1609 void mm_camcorder_client_destroy(MMHandleType handle)
1611 mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
1613 _mmcam_dbg_log("try lock");
1615 if (!_MMCAMCORDER_TRYLOCK_CMD(hcamcorder)) {
1616 _mmcam_dbg_err("Another command is running.");
1617 goto _ERR_CAMCORDER_CMD_PRECON;
1620 if (hcamcorder->attributes) {
1621 _mmcamcorder_dealloc_attribute(handle, hcamcorder->attributes);
1624 _mmcam_dbg_log("unlock");
1625 _MMCAMCORDER_UNLOCK_CMD(hcamcorder);
1627 pthread_mutex_destroy(&((hcamcorder->mtsafe).lock));
1628 pthread_cond_destroy(&((hcamcorder->mtsafe).cond));
1629 pthread_mutex_destroy(&((hcamcorder->mtsafe).cmd_lock));
1630 pthread_mutex_destroy(&((hcamcorder->mtsafe).state_lock));
1631 pthread_mutex_destroy(&((hcamcorder->mtsafe).gst_state_lock));
1632 pthread_mutex_destroy(&((hcamcorder->mtsafe).message_cb_lock));
1633 pthread_mutex_destroy(&(hcamcorder->restart_preview_lock));
1634 _mmcamcorder_set_state((MMHandleType)hcamcorder, MM_CAMCORDER_STATE_NONE);
1635 /* Release handle */
1636 memset(hcamcorder, 0x00, sizeof(mmf_camcorder_t));
1639 _ERR_CAMCORDER_CMD_PRECON:
1643 int mm_camcorder_client_realize(MMHandleType handle, char *caps)
1645 int ret = MM_ERROR_NONE;
1646 ret = _mmcamcorder_client_realize(handle, caps);
1650 int mm_camcorder_client_unrealize(MMHandleType handle)
1652 int ret = MM_ERROR_NONE;
1653 ret = _mmcamcorder_client_unrealize(handle);
1657 int mm_camcorder_client_set_shm_socket_path(MMHandleType handle, const char *path)
1659 int ret = MM_ERROR_NONE;
1660 _mmcam_dbg_log("Entered ");
1661 ret = _mm_camcorder_client_set_shm_socket_path(handle, path);
1665 int mm_camcorder_client_get_root_directory(char **root_directory)
1667 int ret = STORAGE_ERROR_NONE;
1669 if (root_directory == NULL) {
1670 _mmcam_dbg_warn("user data is NULL");
1671 return MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
1674 ret = storage_foreach_device_supported((storage_device_supported_cb)_storage_device_supported_cb, root_directory);
1675 if (ret != STORAGE_ERROR_NONE) {
1676 _mmcam_dbg_err("storage_foreach_device_supported failed 0x%x", ret);
1677 return MM_ERROR_CAMCORDER_INTERNAL;
1680 return MM_ERROR_NONE;