Modify not to destroy handle inside of the resource release callback
[platform/core/multimedia/libmm-wfd.git] / src / mm_wfd_sink_priv.c
index 6fdb339..5244044 100644 (file)
@@ -24,6 +24,7 @@
 #include <gst/video/videooverlay.h>
 #include <Elementary.h>
 #include <Ecore_Wl2.h>
+#include <sys/syscall.h>
 
 #include "mm_wfd_sink_util.h"
 #include "mm_wfd_sink_priv.h"
@@ -66,18 +67,16 @@ __resource_release_cb(mm_resource_manager_h rm, mm_resource_manager_res_h res,
 
        wfd_sink_debug("resource is interrupted. resource would be released after destroying");
 
+       MMWFDSINK_CMD_LOCK(wfdsink);
        if (_mm_wfd_sink_disconnect(wfdsink) != MM_ERROR_NONE)
                wfd_sink_error("failed to disconnect");
 
        if (_mm_wfd_sink_unprepare(wfdsink) != MM_ERROR_NONE)
                wfd_sink_error("failed to unprepare");
-
-       if (_mm_wfd_sink_destroy(wfdsink) != MM_ERROR_NONE)
-               wfd_sink_error("failed to destroy");
-
        for (res_idx = MM_WFD_SINK_RESOURCE_TYPE_VIDEO_DECODER; res_idx < MM_WFD_SINK_RESOURCE_TYPE_MAX; res_idx++) {
                wfdsink->hw_resource[res_idx] = NULL;
        }
+       MMWFDSINK_CMD_UNLOCK(wfdsink);
 
        wfd_sink_debug_fleave();
        return TRUE; /* release all the resources */
@@ -4203,110 +4202,38 @@ static int __mm_wfd_sink_prepare_videosink(mm_wfd_sink_t *wfd_sink, GstElement *
 
        /* configuring display */
        switch (surface_type) {
-               case MM_DISPLAY_SURFACE_EVAS: {
-                               void *object = NULL;
-                               gint scaling = 0;
-
-                               /* common case if using evas surface */
-                               mm_attrs_get_data_by_name(wfd_sink->attrs, "display_overlay", &object);
-                               mm_attrs_get_int_by_name(wfd_sink->attrs, "display_evas_do_scaling", &scaling);
-                               if (object) {
-                                       wfd_sink_debug("set video param : evas-object %p", object);
-                                       g_object_set(G_OBJECT(video_sink), "evas-object", object, NULL);
-                               } else {
-                                       wfd_sink_error("no evas object");
-                                       return MM_ERROR_WFD_INTERNAL;
-                               }
-                       }
-                       break;
-
-               case MM_DISPLAY_SURFACE_OVERLAY: {
-                               static unsigned int wl_surface_id = 0;
-                               static void *display_overlay = NULL;
-                               int wl_window_x = 0;
-                               int wl_window_y = 0;
-                               int wl_window_width = 0;
-                               int wl_window_height = 0;
-                               struct wl_surface *wl_surface = NULL;
-                               struct wl_display *wl_display = NULL;
-                               Ecore_Wl2_Window *wl2_window = NULL;
-                               Ecore_Wl2_Display *wl2_display = NULL;
-                               wl_client *wlclient = NULL;
-                               Evas_Object *obj = NULL;
-                               void *object = NULL;
-                               const char *object_type = NULL;
-                               int ret = 0;
-
-                               mm_attrs_get_data_by_name(wfd_sink->attrs, "display_overlay", &object);
-
-                               if (object != NULL) {
-                                       obj = (Evas_Object *)object;
-                                       object_type = evas_object_type_get(obj);
-                                       wfd_sink_debug("window object type : %s", object_type);
-
-                                       /* wayland overlay surface */
-                                       LOGI("Wayland overlay surface type");
-                                       evas_object_geometry_get(obj, &wl_window_x, &wl_window_y, &wl_window_width, &wl_window_height);
-
-                                       wfd_sink_debug("x[%d] y[%d] width[%d] height[%d]", wl_window_x, wl_window_y,
-                                                                       wl_window_width, wl_window_height);
-
-                                       wl2_window = ecore_evas_wayland2_window_get(ecore_evas_ecore_evas_get(evas_object_evas_get(obj)));
-                                       ecore_wl2_window_video_has(wl2_window, EINA_TRUE);
-                                       wl_surface = ecore_wl2_window_surface_get(wl2_window);
-
-                                       /* get wl_display */
-                                       wl2_display = ecore_wl2_connected_display_get(NULL);
-                                       wl_display = ecore_wl2_display_get(wl2_display);
-
-                                       wfd_sink_debug("previous display object : %p current object : %p", display_overlay, object);
-                                       if (wl_surface && wl_display && (wl_surface_id == 0 || display_overlay != object)) {
-                                               wfd_sink_debug("surface = %p, wl_display = %p", wl_surface, wl_display);
-                                               display_overlay = object;
-
-                                               ret = mm_wfd_sink_wlclient_create(&wlclient);
-                                               if (ret != MM_ERROR_NONE) {
-                                                       wfd_sink_error("Wayland client create failure");
-                                                       return ret;
-                                               }
-                                               wfd_sink_debug("Try to get surface id");
-
-                                               wl_surface_id = mm_wfd_sink_wlclient_get_wl_window_wl_surface_id(wlclient, wl_surface, wl_display);
-
-                                               wfd_sink_debug("wl_surface_id = %d", wl_surface_id);
-
-                                               if (wlclient) {
-                                                       g_free(wlclient);
-                                                       wlclient = NULL;
-                                               }
-                                       }
-                                       wfd_sink_debug("set video param : surface_id %d", wl_surface_id);
-
-                                       if (USE_EXTERNAL_WL_DISPLAY_HANDLE) {
-                                               gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(video_sink),
-                                                                                                               wl_surface_id);
-                                       } else {
-                                               gst_video_overlay_set_wl_window_wl_surface_id(GST_VIDEO_OVERLAY(video_sink),
-                                                                                                                               wl_surface_id);
-                                       }
-                               } else {
-                                       wfd_sink_debug("display object is NULL!");
-                                       return MM_ERROR_WFD_INTERNAL;
-                               }
-                       }
-                       break;
-
-               case MM_DISPLAY_SURFACE_NULL: {
-                               /* do nothing */
-                               wfd_sink_error("Not Supported Surface.");
-                               return MM_ERROR_WFD_INTERNAL;
-                       }
-                       break;
-               default: {
-                               wfd_sink_error("Not Supported Surface.(default case)");
+       case MM_DISPLAY_SURFACE_EVAS: {
+                       void *object = NULL;
+                       gint scaling = 0;
+
+                       /* common case if using evas surface */
+                       mm_attrs_get_data_by_name(wfd_sink->attrs, "display_overlay", &object);
+                       mm_attrs_get_int_by_name(wfd_sink->attrs, "display_evas_do_scaling", &scaling);
+                       if (object) {
+                               wfd_sink_debug("set video param : evas-object %p", object);
+                               g_object_set(G_OBJECT(video_sink), "evas-object", object, NULL);
+                       } else {
+                               wfd_sink_error("no evas object");
                                return MM_ERROR_WFD_INTERNAL;
                        }
-                       break;
+               }
+               break;
+       case MM_DISPLAY_SURFACE_OVERLAY:
+               if (USE_EXTERNAL_WL_DISPLAY_HANDLE) {
+                       gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(video_sink),
+                                                                                       wfd_sink->display_surface_id);
+               } else {
+                       gst_video_overlay_set_wl_window_wl_surface_id(GST_VIDEO_OVERLAY(video_sink),
+                                                                                                       wfd_sink->display_surface_id);
+               }
+               break;
+       case MM_DISPLAY_SURFACE_NULL:
+               /* do nothing */
+               wfd_sink_error("Not Supported Surface.");
+               return MM_ERROR_WFD_INTERNAL;
+       default:
+               wfd_sink_error("Not Supported Surface.(default case)");
+               return MM_ERROR_WFD_INTERNAL;
        }
 
        g_object_set(G_OBJECT(video_sink), "qos", FALSE, NULL);
@@ -5044,6 +4971,88 @@ int _mm_wfd_sink_set_resolution(mm_wfd_sink_t *wfd_sink, MMWFDSinkResolution res
        return MM_ERROR_NONE;
 }
 
+int _mm_wfd_sink_set_display_overlay(mm_wfd_sink_t *wfd_sink, void *display_object)
+{
+       int wl_surface_id = 0;
+       static void *display_overlay = NULL;
+       int wl_window_x = 0;
+       int wl_window_y = 0;
+       int wl_window_width = 0;
+       int wl_window_height = 0;
+       struct wl_surface *wl_surface = NULL;
+       struct wl_display *wl_display = NULL;
+       Ecore_Wl2_Window *wl2_window = NULL;
+       Ecore_Wl2_Display *wl2_display = NULL;
+       wl_client *wlclient = NULL;
+       Evas_Object *obj = NULL;
+       void *object = display_object;
+       const char *object_type = NULL;
+       int ret = 0;
+       pid_t pid = getpid();
+       pid_t tid = syscall(SYS_gettid);
+
+       if (pid != tid) {
+               wfd_sink_error("API isn't called in main thread");
+               return MM_ERROR_WFD_INTERNAL;
+       }
+
+       if (object == NULL) {
+               wfd_sink_debug("display object is NULL!");
+               return MM_ERROR_WFD_INTERNAL;
+       }
+       obj = (Evas_Object *)object;
+       object_type = evas_object_type_get(obj);
+       wfd_sink_debug("window object type : %s", object_type);
+
+       if (strcmp(object_type, "elm_win")) {
+               wfd_sink_error("Window type is not elm_win");
+               return MM_ERROR_WFD_INTERNAL;
+       }
+
+       /* wayland overlay surface */
+       wfd_sink_info("Wayland overlay surface type");
+       evas_object_geometry_get(obj, &wl_window_x, &wl_window_y, &wl_window_width, &wl_window_height);
+
+       wfd_sink_debug("x[%d] y[%d] width[%d] height[%d]", wl_window_x, wl_window_y,
+                                       wl_window_width, wl_window_height);
+
+       wl2_window = ecore_evas_wayland2_window_get(ecore_evas_ecore_evas_get(evas_object_evas_get(obj)));
+       ecore_wl2_window_video_has(wl2_window, EINA_TRUE);
+       wl_surface = ecore_wl2_window_surface_get(wl2_window);
+
+       /* get wl_display */
+       wl2_display = ecore_wl2_connected_display_get(NULL);
+       wl_display = ecore_wl2_display_get(wl2_display);
+
+       wfd_sink_debug("previous display object : %p current object : %p", display_overlay, object);
+       if (wl_surface && wl_display && (wl_surface_id == 0 || display_overlay != object)) {
+               wfd_sink_debug("surface = %p, wl_display = %p", wl_surface, wl_display);
+               display_overlay = object;
+
+               ret = mm_wfd_sink_wlclient_create(&wlclient);
+               if (ret != MM_ERROR_NONE) {
+                       wfd_sink_error("Wayland client create failure");
+                       return MM_ERROR_WFD_INTERNAL;
+               }
+               wfd_sink_debug("Try to get surface id");
+
+               wl_surface_id = mm_wfd_sink_wlclient_get_wl_window_wl_surface_id(wlclient, wl_surface, wl_display);
+
+               wfd_sink_debug("wl_surface_id = %d", wl_surface_id);
+               if (wl_surface_id == 0) {
+                       wfd_sink_error("wl_surface_id cannot be zero.");
+                       return MM_ERROR_WFD_INTERNAL;
+               }
+               wfd_sink->display_surface_id = wl_surface_id;
+
+               if (wlclient) {
+                       g_free(wlclient);
+                       wlclient = NULL;
+               }
+       }
+       return MM_ERROR_NONE;
+}
+
 void __mm_wfd_sink_print_ref_count(mm_wfd_sink_t *wfd_sink)
 {
        int i = 0;