AC_SUBST(GST_APP_CFLAGS)
AC_SUBST(GST_APP_LIBS)
-AC_ARG_ENABLE(wayland, AC_HELP_STRING([--enable-wayland], [enable wayland]),
-[
- case "${enableval}" in
- yes) WAYLAND_SUPPORT=yes ;;
- no) WAYLAND_SUPPORT=no ;;
- *) AC_MSG_ERROR(bad value ${enableval} for --enable-wayland) ;;
- esac
-],[WAYLAND_SUPPORT=no])
-if test "x$WAYLAND_SUPPORT" = "xyes"; then
PKG_CHECK_MODULES(GST_WAYLAND, gstreamer-wayland-1.0 >= 1.2.0)
AC_SUBST(GST_WAYLAND_CFLAGS)
AC_SUBST(GST_WAYLAND_LIBS)
-fi
-AM_CONDITIONAL([WAYLAND_SUPPORT], [test "x$WAYLAND_SUPPORT" = "xyes"])
PKG_CHECK_MODULES(MM_COMMON, mm-common)
AC_SUBST(MM_COMMON_CFLAGS)
-%bcond_with wayland
-
Name: libmm-camcorder
Summary: Camera and recorder library
-Version: 0.10.61
+Version: 0.10.62
Release: 0
Group: Multimedia/Libraries
License: Apache-2.0
BuildRequires: pkgconfig(gstreamer-base-1.0)
BuildRequires: pkgconfig(gstreamer-video-1.0)
BuildRequires: pkgconfig(gstreamer-app-1.0)
-%if %{with wayland}
BuildRequires: pkgconfig(gstreamer-wayland-1.0)
BuildRequires: pkgconfig(wayland-client)
-%endif
BuildRequires: pkgconfig(vconf)
BuildRequires: pkgconfig(libtbm)
BuildRequires: pkgconfig(storage)
%build
-%if %{with wayland}
-export CFLAGS+=" -DHAVE_WAYLAND -DGST_USE_UNSTABLE_API"
-%endif
-export CFLAGS+=" -D_LARGEFILE64_SOURCE -DSYSCONFDIR=\\\"%{_sysconfdir}\\\" -DTZ_SYS_ETC=\\\"%{TZ_SYS_ETC}\\\""
+export CFLAGS+=" -D_LARGEFILE64_SOURCE -DGST_USE_UNSTABLE_API -DSYSCONFDIR=\\\"%{_sysconfdir}\\\" -DTZ_SYS_ETC=\\\"%{TZ_SYS_ETC}\\\""
./autogen.sh
%configure \
-%if %{with wayland}
- --enable-wayland \
-%endif
%if "%{TIZEN_PRODUCT_TV}" != "1"
--enable-murphy \
%else
$(GST_PLUGIN_BASE_CFLAGS) \
$(GST_VIDEO_CFLAGS) \
$(GST_APP_CFLAGS) \
+ $(GST_WAYLAND_CFLAGS) \
$(EXIF_CFLAGS) \
$(MM_COMMON_CFLAGS) \
$(MMSOUND_CFLAGS) \
$(GST_PLUGIN_BASE_LIBS) \
$(GST_VIDEO_LIBS) \
$(GST_APP_LIBS) \
+ $(GST_WAYLAND_LIBS) \
$(MM_COMMON_LIBS) \
$(EXIF_LIBS) \
$(MMSOUND_LIBS) \
libmmfcamcorder_la_LDFLAGS = -Wl,--gc-sections
libmmfcamcorder_la_LIBADD += $(SYSTEMINFO_LIBS)
-if WAYLAND_SUPPORT
-libmmfcamcorder_la_CFLAGS += $(GST_WAYLAND_CFLAGS)
-libmmfcamcorder_la_LIBADD += $(GST_WAYLAND_LIBS)
-endif
-
if MURPHY_SUPPORT
libmmfcamcorder_la_SOURCES += mm_camcorder_resource.c
libmmfcamcorder_la_CFLAGS += $(MURPHY_RESOURCE_CFLAGS) $(MURPHY_GLIB_CFLAGS) -D_MMCAMCORDER_MURPHY_SUPPORT
* The type of PTZ(Pan Tilt Zoom). Mechanical or Electonic PTZ.
*/
#define MMCAM_CAMERA_PTZ_TYPE "camera-ptz-type"
+
/**
* Stream type and index for sound route
*/
#define MMCAM_SOUND_STREAM_TYPE "sound-stream-type"
#define MMCAM_SOUND_STREAM_INDEX "sound-stream-index"
+/**
+ * The display reuse flag and sink element pointer
+ */
+#define MMCAM_DISPLAY_REUSE_HINT "display-reuse-hint"
+#define MMCAM_DISPLAY_REUSE_ELEMENT "display-reuse-element"
+
/*=======================================================================================
| ENUM DEFINITIONS |
========================================================================================*/
MMCamFaceInfo *face_info; /**< face information, this should be freed after use it. */
} MMCamFaceDetectInfo;
-#ifdef HAVE_WAYLAND
/**
* Wayland information
*/
int window_height;
void *evas_obj;
} MMCamWaylandInfo;
-#endif /* HAVE_WAYLAND */
+
/*=======================================================================================
| TYPE DEFINITIONS |
MM_CAM_ROOT_DIRECTORY,
MM_CAM_SOUND_STREAM_TYPE,
MM_CAM_SOUND_STREAM_INDEX,
+ MM_CAM_DISPLAY_REUSE_HINT,
+ MM_CAM_DISPLAY_REUSE_ELEMENT,
MM_CAM_ATTRIBUTE_NUM
}MMCamcorderAttrsID;
elist = g_list_append(elist, &(element[eid])); \
}
+#define _MMCAMCORDER_ELEMENT_ADD(sub_context, element, eid, gst_element, elist, err) \
+ if (element[eid].gst != NULL) { \
+ _mmcam_dbg_err("The element is existed. element_id=[%d]", eid); \
+ gst_object_unref(element[eid].gst); \
+ } \
+ element[eid].gst = gst_element; \
+ if (element[eid].gst == NULL) { \
+ _mmcam_dbg_err("Element is NULL. element_id=[%d]", eid); \
+ err = MM_ERROR_CAMCORDER_RESOURCE_CREATION; \
+ goto pipeline_creation_error; \
+ } else { \
+ _mmcam_dbg_log("Adding Element is done. element_id=[%d] %p", eid, gst_element); \
+ element[eid].id = eid; \
+ g_object_weak_ref(G_OBJECT(element[eid].gst), (GWeakNotify)_mmcamcorder_element_release_noti, sub_context); \
+ err = MM_ERROR_NONE; \
+ } \
+ elist = g_list_append(elist, &(element[eid]));
+
#define _MMCAMCORDER_ENCODEBIN_ELMGET(sub_context, eid, name /*char* */, err) \
if (sub_context->encode_element[eid].gst != NULL) { \
_mmcam_dbg_err("The element is existed. element_id=[%d], name=[%s]", eid, name); \
*/
typedef enum {
_MMCAMCORDER_STATE_CHANGE_NORMAL = 0,
- _MMCAMCORDER_STATE_CHANGE_BY_ASM,
+ _MMCAMCORDER_STATE_CHANGE_BY_FOCUS,
_MMCAMCORDER_STATE_CHANGE_BY_RM,
_MMCAMCORDER_STATE_CHANGE_BY_DPM
} _MMCamcorderStateChange;
#include <gst/video/colorbalance.h>
#include <gst/video/cameracontrol.h>
#include <gst/video/videooverlay.h>
-#ifdef HAVE_WAYLAND
#include <gst/wayland/wayland.h>
-#endif
/*-----------------------------------------------------------------------
| MACRO DEFINITIONS: |
{.int_min = -1},
{.int_max = _MMCAMCORDER_MAX_INT},
_mmcamcorder_commit_sound_stream_info,
+ },
+ {
+ MM_CAM_DISPLAY_REUSE_HINT,
+ "display-reuse-hint",
+ MMF_VALUE_TYPE_INT,
+ MM_ATTRS_FLAG_RW,
+ {(void*)FALSE},
+ MM_ATTRS_VALID_TYPE_INT_RANGE,
+ {.int_min = FALSE},
+ {.int_max = TRUE},
+ NULL,
+ },
+ {
+ MM_CAM_DISPLAY_REUSE_ELEMENT,
+ "display-reuse-element",
+ MMF_VALUE_TYPE_DATA,
+ MM_ATTRS_FLAG_RW,
+ {(void*)NULL},
+ MM_ATTRS_VALID_TYPE_NONE,
+ {0},
+ {0},
+ NULL,
}
};
!strcmp(videosink_name, "evaspixmapsink")) {
_mmcam_dbg_log("Commit : Set evas object [%p]", p_handle);
MMCAMCORDER_G_OBJECT_SET_POINTER(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "evas-object", p_handle);
-#ifdef HAVE_WAYLAND
} else if (!strcmp(videosink_name, "waylandsink")) {
MMCamWaylandInfo *wl_info = (MMCamWaylandInfo *)p_handle;
gst_video_overlay_set_wl_window_wl_surface_id(GST_VIDEO_OVERLAY(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst), (guintptr)wl_info->global_surface_id);
gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst),
wl_info->window_x, wl_info->window_y, wl_info->window_width, wl_info->window_height);
-#endif /* HAVE_WAYLAND */
} else {
_mmcam_dbg_warn("Commit : Nothing to commit with this element[%s]", videosink_name);
return FALSE;
#include <gst/audio/audio-format.h>
#include <gst/video/videooverlay.h>
#include <gst/video/cameracontrol.h>
-#ifdef HAVE_WAYLAND
#include <gst/wayland/wayland.h>
-#endif
#include <sys/time.h>
#include <unistd.h>
int decoder_index = 0;
char decoder_name[20] = {'\0',};
#endif /* _MMCAMCORDER_RM_SUPPORT */
+ GstElement *sink_element = NULL;
+ int sink_element_size = 0;
GList *element_list = NULL;
g_object_set(G_OBJECT(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst), "socket-path", socket_path, NULL);
} else {
-
if (hcamcorder->use_videoconvert && !strcmp(videosink_name, "waylandsink")) {
/* get video convert name */
_mmcamcorder_conf_get_value_element_name(sc->VideoconvertElement, &videoconvert_name);
_mmcam_dbg_err("failed to get videoconvert element name");
}
- _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_VIDEOSINK_SINK, videosink_name, "videosink_sink", element_list, err);
+ /* check sink element in attribute */
+ mm_camcorder_get_attributes(handle, NULL,
+ MMCAM_DISPLAY_REUSE_ELEMENT, &sink_element, &sink_element_size,
+ NULL);
- _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, sc->VideosinkElement);
+ if (sink_element) {
+ int attr_index = 0;
+ mmf_attrs_t *attrs = MMF_CAMCORDER_ATTRS(handle);
+ mmf_attribute_t *attr_item = NULL;
+
+ _mmcam_dbg_log("reuse sink element %p in attribute", sink_element);
+
+ _MMCAMCORDER_ELEMENT_ADD(sc, sc->element, _MMCAMCORDER_VIDEOSINK_SINK, sink_element, element_list, err);
+
+ /* reset attribute */
+ if (attrs) {
+ mm_attrs_get_index((MMHandleType)attrs, MMCAM_DISPLAY_REUSE_ELEMENT, &attr_index);
+ attr_item = &attrs->items[attr_index];
+ mmf_attribute_set_data(attr_item, NULL, 0);
+ mmf_attribute_commit(attr_item);
+ } else {
+ _mmcam_dbg_warn("attribute is NULL");
+ err = MM_ERROR_CAMCORDER_NOT_INITIALIZED;
+ goto pipeline_creation_error;
+ }
+ } else {
+ _MMCAMCORDER_ELEMENT_MAKE(sc, sc->element, _MMCAMCORDER_VIDEOSINK_SINK, videosink_name, "videosink_sink", element_list, err);
+
+ _mmcamcorder_conf_set_value_element_property(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, sc->VideosinkElement);
+ }
if (_mmcamcorder_videosink_window_set(handle, sc->VideosinkElement) != MM_ERROR_NONE) {
_mmcam_dbg_err("_mmcamcorder_videosink_window_set error");
_mmcam_dbg_err("display handle(eavs object) is NULL");
return MM_ERROR_CAMCORDER_INVALID_ARGUMENT;
}
-#ifdef HAVE_WAYLAND
} else if (!strcmp(videosink_name, "waylandsink")) {
MMCamWaylandInfo *wl_info = (MMCamWaylandInfo *)overlay;
if (wl_info) {
gst_video_overlay_set_render_rectangle(GST_VIDEO_OVERLAY(vsink),
wl_info->window_x, wl_info->window_y, wl_info->window_width, wl_info->window_height);
#ifdef _MMCAMCORDER_RM_SUPPORT
- if (hcamcorder->request_resources.category_id[0] == RM_CATEGORY_VIDEO_DECODER_SUB)
- display_scaler = 1;
+ if (hcamcorder->request_resources.category_id[0] == RM_CATEGORY_VIDEO_DECODER_SUB)
+ display_scaler = 1;
- MMCAMCORDER_G_OBJECT_SET(vsink, "device-scaler", display_scaler);
+ MMCAMCORDER_G_OBJECT_SET(vsink, "device-scaler", display_scaler);
#endif /* _MMCAMCORDER_RM_SUPPORT */
} else {
_mmcam_dbg_warn("Handle is NULL. skip setting.");
}
-#endif /* HAVE_WAYLAND */
} else {
_mmcam_dbg_warn("Who are you?? (Videosink: %s)", videosink_name);
}
#ifdef _MMCAMCORDER_RM_SUPPORT
int iret = RM_OK;
#endif /* _MMCAMCORDER_RM_SUPPORT */
+ GstElement *sink_element = NULL;
+ int sink_element_size = 0;
mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
g_cond_signal(&hcamcorder->task_thread_cond);
g_mutex_unlock(&hcamcorder->task_thread_lock);
+ /* remove kept, but not used sink element in attribute */
+ mm_camcorder_get_attributes(handle, NULL,
+ MMCAM_DISPLAY_REUSE_ELEMENT, &sink_element, &sink_element_size,
+ NULL);
+ if (sink_element) {
+ GstStateChangeReturn result = gst_element_set_state(sink_element, GST_STATE_NULL);
+
+ _mmcam_dbg_warn("remove sink element %p, set state NULL result %d", sink_element, result);
+
+ gst_object_unref(sink_element);
+ sink_element = NULL;
+ }
+
/* wait for completion of sound play */
_mmcamcorder_sound_solo_play_wait(handle);
hcamcorder->state_change_by_system, hcamcorder->session_flags, hcamcorder->acquired_focus,
hcamcorder->sound_focus_id, hcamcorder->sound_focus_watch_id);
- if (hcamcorder->state_change_by_system != _MMCAMCORDER_STATE_CHANGE_BY_ASM &&
+ if (hcamcorder->state_change_by_system != _MMCAMCORDER_STATE_CHANGE_BY_FOCUS &&
hcamcorder->sound_focus_watch_id > 0) {
ret_sound = mm_sound_unset_focus_watch_callback(hcamcorder->sound_focus_watch_id);
if (ret_sound != MM_ERROR_NONE) {
/* To discern who changes the state */
switch (hcamcorder->state_change_by_system) {
- case _MMCAMCORDER_STATE_CHANGE_BY_ASM:
+ case _MMCAMCORDER_STATE_CHANGE_BY_FOCUS:
msg.id = MM_MESSAGE_CAMCORDER_STATE_CHANGED_BY_ASM;
msg.param.state.code = hcamcorder->interrupt_code;
break;
_MMCAMCORDER_LOCK_ASM(hcamcorder);
/* set value to inform a status is changed by asm */
- hcamcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_BY_ASM;
+ hcamcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_BY_FOCUS;
/* check the reason */
if (!strncmp(reason_for_change, "ringtone-voip", __MMCAMCORDER_FOCUS_CHANGE_REASON_LEN) ||
_MMCAMCORDER_LOCK_ASM(hcamcorder);
/* set value to inform a status is changed by asm */
- hcamcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_BY_ASM;
+ hcamcorder->state_change_by_system = _MMCAMCORDER_STATE_CHANGE_BY_FOCUS;
/* check the reason */
if (!strncmp(reason_for_change, "ringtone-voip", __MMCAMCORDER_FOCUS_CHANGE_REASON_LEN) ||
return cb_res;
}
-#endif /* _MMCAMCORDER_RM_SUPPORT */
\ No newline at end of file
+#endif /* _MMCAMCORDER_RM_SUPPORT */
{
mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
_MMCamcorderSubContext *sc = NULL;
+ int display_reuse_hint = FALSE;
+ GstElement *sink_element = NULL;
+ mmf_attrs_t *attrs = NULL;
+ int attr_index = 0;
+ mmf_attribute_t *attr_item = NULL;
mmf_return_if_fail(hcamcorder);
MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "empty-buffers", TRUE);
MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", TRUE);
+ /* check reuse flag for display element */
+ mm_camcorder_get_attributes(handle, NULL,
+ MMCAM_DISPLAY_REUSE_HINT, &display_reuse_hint,
+ NULL);
+
+ _mmcam_dbg_log("display reuse hint %d", display_reuse_hint);
+
+ if (!display_reuse_hint)
+ goto _REUSE_CHECK_DONE;
+
+ sink_element = sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst;
+ if (!sink_element) {
+ _mmcam_dbg_warn("sink element is NULL");
+ goto _REUSE_CHECK_DONE;
+ }
+
+ attrs = (mmf_attrs_t *)MMF_CAMCORDER_ATTRS(handle);
+ if (!attrs) {
+ _mmcam_dbg_warn("attribute is NULL");
+ goto _REUSE_CHECK_DONE;
+ }
+
+ _mmcam_dbg_log("REF sink element %p and set it to attribute", sink_element);
+
+ /* ref element before remove it from pipeline */
+ gst_object_ref(sink_element);
+
+ if (!gst_bin_remove(GST_BIN(sc->element[_MMCAMCORDER_MAIN_PIPE].gst), sink_element)) {
+ _mmcam_dbg_warn("failed to remove sink element from pipeline");
+ }
+
+ /* set sink element pointer to attribute */
+ mm_attrs_get_index((MMHandleType)attrs, MMCAM_DISPLAY_REUSE_ELEMENT, &attr_index);
+ attr_item = &attrs->items[attr_index];
+ mmf_attribute_set_data(attr_item, (void *)sink_element, sizeof(sink_element));
+ mmf_attribute_commit(attr_item);
+
+ /* remove notify callback */
+ g_object_weak_unref(G_OBJECT(sink_element), (GWeakNotify)_mmcamcorder_element_release_noti, sc);
+
+ sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst = NULL;
+ sc->element[_MMCAMCORDER_VIDEOSINK_SINK].id = _MMCAMCORDER_NONE;
+
+_REUSE_CHECK_DONE:
traceBegin(TTRACE_TAG_CAMERA, "MMCAMCORDER:UNREALIZE:SET_NULL_TO_PIPELINE");
_mmcamcorder_gst_set_state(handle, sc->element[_MMCAMCORDER_MAIN_PIPE].gst, GST_STATE_NULL);
int ret = MM_ERROR_NONE;
int strobe_mode = MM_CAMCORDER_STROBE_MODE_OFF;
int set_strobe = 0;
+ int display_reuse_hint = FALSE;
GstCameraControl *control = NULL;
mmf_camcorder_t *hcamcorder = MMF_CAMCORDER(handle);
_mmcamcorder_remove_recorder_pipeline(handle);
}
- /* Disable skip flush buffer */
- MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "enable-flush-buffer", FALSE);
+ mm_camcorder_get_attributes(handle, NULL,
+ MMCAM_DISPLAY_REUSE_HINT, &display_reuse_hint,
+ NULL);
+
+ _mmcam_dbg_log("display reuse hint %d", display_reuse_hint);
+
+ MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "keep-camera-preview", display_reuse_hint);
MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "empty-buffers", TRUE);
MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", TRUE);
MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_QUE].gst, "empty-buffers", FALSE);
MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSRC_QUE].gst, "empty-buffers", FALSE);
- /* Enable skip flush buffer */
- MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "enable-flush-buffer", TRUE);
+ if (display_reuse_hint)
+ MMCAMCORDER_G_OBJECT_SET(sc->element[_MMCAMCORDER_VIDEOSINK_SINK].gst, "keep-camera-preview", FALSE);
/* deregister sound status callback */
if (sc->info_image->sound_status != _SOUND_STATUS_INIT) {
}
/* Screennail image buffer */
- attrs = (mmf_attrs_t*)MMF_CAMCORDER_ATTRS(hcamcorder);
+ attrs = (mmf_attrs_t *)MMF_CAMCORDER_ATTRS(hcamcorder);
mm_attrs_get_index((MMHandleType)attrs, MMCAM_CAPTURED_SCREENNAIL, &attr_index);
item_screennail = &attrs->items[attr_index];
_mmcam_dbg_err("");
- if (hcamcorder->state_change_by_system != _MMCAMCORDER_STATE_CHANGE_BY_ASM) {
+ if (hcamcorder->state_change_by_system != _MMCAMCORDER_STATE_CHANGE_BY_FOCUS) {
/* Play record stop sound */
_mmcamcorder_sound_solo_play(handle, _MMCAMCORDER_SAMPLE_SOUND_NAME_REC_STOP, FALSE);
} else {
info->filesize = 0;
info->b_commiting = FALSE;
- if (hcamcorder->state_change_by_system != _MMCAMCORDER_STATE_CHANGE_BY_ASM) {
+ if (hcamcorder->state_change_by_system != _MMCAMCORDER_STATE_CHANGE_BY_FOCUS) {
/* check recording stop sound */
_mmcamcorder_sound_solo_play_wait(handle);
}